一開始想著用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出發訪問剩餘的所有頂...