有乙個n*m(n<=5,m<=1000)的棋盤,現在有1*2及2*1的小木塊無數個,要蓋滿整個棋盤,有多少種方式?答案只需要mod1,000,000,007即可。
//我也不知道這道題的**qaq
n和m的範圍本應是相同的,但是題目給出的n的值很小,這就給我們提供了使用狀壓dp的思路。
假設第一列已經鋪滿,則第二列的情況只與第一列對它的影響有關,同理,第三列的情況也只與第二列對它的影響有關,我們可以利用二進位制來表示某一列的情況,狀態state表示某一列的狀態,例如state=4,則此列狀態為00100,用dp[i][state]表示第i列,第i-1列對它的影響為state的方案數,求每一列的方案數可以通過搜尋來實現,dp[i][state]=sigma(dp[i-1][la]) la可以通過填放變為state。
//鋪棋盤
//2015/10/22
#include#include#include#include#include#include#include#define maxn 100000000+50
#define inf 0x7fffffff
#define xiao 1e-9
#define mod 1000000007
using namespace std;
int dp[1005][40],n,m;
void dfs(int i,int j,int state,int next)
//如果列舉到了最後一行,則下一列狀態為next時方案數加上此列狀態為state的方案數
if(((1<0) dfs(i,j+1,state,next);//如果第j行位置已被占用,直接跳過,搜尋j+1行
if(((1<>n>>m;
memset(dp,0,sizeof(dp));
dp[1][0]=1;
for(int i=1;i<=m;++i)
for(int j=0;j<(1
}
POJ 1321 棋盤問題(DFS 狀壓DP)
用dfs寫當然很簡單了,8!的複雜度,16ms搞定。在discuss裡看到有同學用狀態壓縮dp來寫,就學習了一下,果然很精妙呀。狀態轉移分兩種,當前行不加棋子,和加棋子。dp i j 中,i代表行數,j代表當前行棋子的狀態。j的二進位制中,1代表有旗子,0代表無棋子。貼 狀壓dp果然快一點。incl...
狀壓dp之棋盤覆蓋
1.poj2411 題目大意 用2 1的骨牌覆蓋滿乙個n m的矩陣,求方案數。n,m 11 題目分析 由於n和m都很小,可以想到狀態壓縮dp。如果我們f i j 表示某i行的狀態j,在狀態j中,1表示已經覆蓋,0表示沒有覆蓋,那麼有三種情況 1.不放 2.橫著放 3.豎著放。用dfs來尋找每行和它上...
狀壓dp學習
p2704 炮兵陣地 1038 裁玻璃 狀壓dp是一種非常暴力的做法,列舉所有可能的狀態,找到要求的最佳狀態,與一般dp不同,前一項與後一項有一些複雜的狀態關係。dp的引數 物品個數 行數等 當前狀態 上乙個狀態 將abc的有無表示成乙個8個狀態,列舉所有組,列舉上乙個狀態,得到當前狀態的最優解 i...