求把n * m的棋盤分割成若干個1*2的的長方形,有多少種方案。輸入格式例如當n=2,m=4時,共有5種方案。當n=2,m=3時,共有3種方案。
如下圖所示:
輸入包含多組測試用例。輸出格式每組測試用例佔一行,包含兩個整數n和m。
當輸入用例n=0,m=0時,表示輸入終止,且該用例無需處理。
每個測試用例輸出乙個結果,每個結果佔一行。資料範圍
1≤ n,m ≤11
輸入樣例1 21 3題目分析:1 42 2
2 32 4
2 11
4 11
0 0輸出樣例10
1235
14451205
這是一道狀態壓縮dp。我們可以先計算出所有橫向放置的方格的方法數,當橫向的方格都擺放完後,縱向的方格就只剩下了一種放置方法。
狀態表示:f[i][j] //i表示當前在第i列,j表示從i-1列中伸到第i列(因為是1*2的方格)的方格的狀態
這個狀態可以用二進位制數來表示。
例如:一共5行當前為第i列,當上一列只有第1,3行伸出方格時的狀態為f[i][00101(二進位制)]。
狀態計算:f[i][j]+=sum(f[i-1][k]) (0<=k<1但要注意有兩個約束條件:
1)在第i列放方格的位置上不能有i-1列伸出的方格,即(j&k)==0
2)因為求的方格為橫著擺放的方格種數,因此在計算時還要考慮當第i列擺放完後,第i列中不能存在連續的奇數個空格,即j|k中不存在連續奇數個0
這乙個條件我們可以通過預處理來得到。
**如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using
namespace std;
intconst n=
12,m=
1<
ll f[n]
[m];
//資料可能會爆int
bool st[m]
;int
main()
else cnt++
;//當前格仔沒有伸出的方格則cnt+1}if
(cnt&
1) st[i]
=false
;//迴圈完後再判斷一次
} f[0]
[0]=
1;//初始化
for(
int i=
1;i<=m;i++
)//i為列數,j為第i列的伸出方格數
for(
int j=
0;j<
1<
)//k為i-1列的伸出方格數
for(
int k=
0;k<
1<
) cout<
]<
//答案為m列沒有方格伸出的情況
}}
蒙德里安的夢想
求把nm的棋盤分割成若干個12的的長方形,有多少種方案。例如當n 2,m 4時,共有5種方案。當n 2,m 3時,共有3種方案。輸入格式 輸入包含多組測試用例。每組測試用例佔一行,包含兩個整數n和m。當輸入用例n 0,m 0時,表示輸入終止,且該用例無需處理。輸出格式 每個測試用例輸出乙個結果,每個...
蒙德里安的夢想
acwing rua,可以分割棋盤,但是我們發現分割棋盤之後會有好多長方形被攔腰折斷,所以可以沒被折斷的看做 0,折斷的看做 1,那麼下一行中那些折斷的就必須看做 0,剩下的可以是1 也可以是 0。用 f 表示第 i 行的形態 為 j 時,前 i 行的分割方案的總數。第 i 1 的形態 k 轉移到第...
AcWing , 蒙德里安的夢想
結果完整 就是將乙個n m的二維矩陣,分成若干個1 2的方格,有多少種分配方式 完全分配 可以對放置的方式進行模擬,先放置橫著的1 2方格,再放置豎著的2 1方格。那麼擺放的小方格方案數等價於橫著擺放的小方格方案數,因為當橫著合法擺放的方格確定後,豎著擺放的方式就已經確定了,直接內嵌。他的資料範圍為...