291 蒙德里安的夢想

2022-09-28 02:54:09 字數 1697 閱讀 9926

求把 \(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 2

1 31 4

2 22 3

2 42 11

4 11

0 0

輸出樣例:
101

235144

51205

狀壓dp

分析:總的合法方案數為橫著放小方塊的總的合法方案數,其餘由豎著的小方塊塞進去即可,設當前列 \(i\) 由前面開始橫著放的小方塊狀態為 \(1\),否則為 \(0\),則其可由 \(i-1\) 轉移過來,注意第一列和最後一列的下一列狀態為 \(0\)

// problem: 蒙德里安的夢想

// contest: acwing

// url:

// memory limit: 64 mb

// time limit: 5000 ms

// // powered by cp editor (

// %%%skyqwq

#include //#define int long long

#define help

#define pb push_back

#define fi first

#define se second

#define mkp make_pair

using namespace std;

typedef long long ll;

typedef pairpii;

typedef pairpll;

template bool chkmax(t &x, t y)

template bool chkmin(t &x, t y)

template void inline read(t &x)

while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();

x *= f;

}const int n=1<<11;

int n,m;

ll f[12][n];

bool st[n];

int main()

else

cnt++;

if(cnt&1)st[i]=false;

} memset(f,0,sizeof f);

f[0][0]=1;

for(int i=1;i<=m;i++)

for(int j=0;j<1<

for(int k=0;k<1<

if((j&k)==0&&st[j|k])f[i][j]+=f[i-1][k];

cout<

}return 0;

}

AW291 蒙德里安的夢想

題目位址 易錯點 結論1 在合法狀態下,對於每個橫塊的正上方兩個格仔中任意乙個格仔,一定屬於某個橫塊的一部分或某個豎塊的下半部.證明 假設有乙個橫塊的正上方兩格中的某格為乙個豎塊的上半部,由定義可知該情況不成立.對於任意乙個格仔,只有可能為以下三種狀態之一 豎塊上半部 豎塊下半部 半個橫塊.由 1 ...

AcWing 291 蒙德里安的夢想

題意 給出 n 11,m 11 的矩陣,要求將矩陣全部恰好分成 1 times 2 或者 2 times 1 的小矩陣,問方案數。題解 主要是dp陣列的含義定義要了解,設 dp 表示的是第 i 行 j 形狀的方案數,這裡的 j 代表的是二進位制的狀態。想象乙個 01 串,然後在串中第 x 個0代表的...

Acwing 291 蒙德里安的夢想

求把 n m 的棋盤分割成若干個 1 2 的的長方形,有多少種方案。1 n,m 11 用f i s 表示第i行狀態為s的方案數 對於s 0表示i 1列無伸向第i列的方格,1表示有伸向第i列的方格 先預處理可用狀態 對這一題所有狀態都可用 state.clear for int i 0 i 1 找可轉...