蒙德里安的夢想

2021-10-04 11:21:57 字數 1883 閱讀 6504

求把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方格。那麼擺放的小方格方案數等價於橫著擺放的小方格方案數,因為當橫著合法擺放的方格確定後,豎著擺放的方式就已經確定了,直接內嵌。他的資料範圍為...