狀態壓縮dp poj2411 1 2磚塊

2021-07-27 22:17:35 字數 1707 閱讀 7776

一開始想著用00,  11表示同乙個磚,但是這樣的話狀態轉移就難了,,然後看題解。題解的狀態就不會衝突。

/*分析:用1*2的磚去恰好鋪滿n*m的空間,對於第k行第j列,有3種情況將該點鋪滿  

1:由第k-1行第j列磚豎著鋪將第k行第j列鋪滿  

2:由第k行第j列被橫鋪磚鋪滿  

3:第k行第j列磚豎著鋪將該點鋪滿  

所以對於每一列的情況其實有兩種(1,0)表示該點鋪磚還是不鋪  

而對於每一列必須到達的狀態只有一種,就是被鋪滿(1)  

但是由上述3種情況將鋪滿方式分成兩種:  

0和1表示被k-1行j列豎鋪鋪滿和在k-1行被橫鋪鋪滿   

對於每一行列舉每一種到達的狀態j,dp[j]表示到達該狀態有多少種情況  

分析對於第k-1行狀態j:10000111  

需要到達第k行狀態i:  01111011  

如果需要到達第k行j列狀態是0,則必須第k-1行該點狀態不能是0,否則一定是連續兩列豎放衝突  

所以到達第k-1行該點只能是1,也就是說i|j一定每一位是1,也可以一步步判斷是否滿足第k行j列是0第k-1行j列是1   

如果需要到達第k行狀態j列是1,則假如第k-1行該點是0,則該點狀態可以到達,繼續判斷j+1列  

假如第k-1行該點是1,則第k行j列的1一定是橫鋪到達的,所以k行第j+1列一定也被鋪滿為1  

從而第k-1行j+1列一定不能豎鋪,必須被橫鋪鋪滿,所以也是1.  

於是綜合的第k行j列和第k-1行j列的關係(每一行每一列都表示到達的狀態)  

1:下面這種情況從第j列繼續去判斷j+1列   

1  0  

2:下面這種情況從第j列繼續去判斷j+1列   

0  1  

3:下面這種情況從第j列判斷第j+1列是否全是1,然後繼續判斷第j+2列  

1  1   

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define inf 99999999

typedef

long

long

ll;  

using

namespace

std;  

const

intmax=(1<<11)+10;  

intn,m;  

ll temp[max],dp[max],bin[15];  

bool

mark[max];  

bool

check(

inti)else

i>>=1;

//繼續判斷下一列 

}  return

true

;  }  

void

init()  

}  void

dp()  

}  for

(int

i=0;i

}  }  

intmain()  

return

0;  

}  

狀態壓縮DP POJ 1170

題意 乙個商店提供多種商品,當使用者單獨購買商品時有乙個 當使用者組合購買時可以獲得優惠,現在提供多種優惠方案和需要購買的物品總數,問最大的優惠是多少。輸入2 7 3 2 8 2 5 21 7 3 5 2 7 1 8 2 10 表示有 2 種商品,編號分別是 7 和 8,分別要購買的數量是 3 和 ...

狀態壓縮DP poj2411 矩形填充木塊問題

從某場筆試遇到的題,群裡太多人改網上 只能對60 我是100 特地記錄下。分析 首先我們定義如下這種填充表示方式 如果乙個骨牌是橫著放的,那麼它所在的兩個方格都填充0.如果它是豎著放的,那麼它所在的兩個格仔中,上面的那個填1,下面的這個填0.如下圖所示 圖來自 部落格 右邊的圖 0 和 1互換就好了...

狀態壓縮DP

首先,我們以一道狀壓經典題tsp來引入。tsp問題 一張圖上有n個點,給定相應的鄰接矩陣,需要求出從0號節點出發,經過且只經過每個頂點一次,最後仍回到0號節點的最小邊權。思路 假設現在已訪問過的頂點集合 起點0當作還未訪問過的頂點 為s,當前所在頂點為v,用dp s v 表示從v出發訪問剩餘的所有頂...