NC51189. Mondriaan's Dream
描述
输入描述
The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0. Otherwise, .
输出描述
For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.
示例1
输入:
1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0
输出:
1 0 1 2 3 5 144 51205
C++(g++ 7.5.0) 解法, 执行用时: 11ms, 内存消耗: 376K, 提交时间: 2023-05-30 22:57:24
#include<bits/stdc++.h> using namespace std; int main() { int h, w; while (cin >> h >> w && h) { //swap(h, w); int sz = 1 << w; vector<long long> cur(sz);; cur[0] = 1; while (h--) { for (int i = 0; i < w; i++) { vector<long long> nxt(sz);; for (int s = 0; s < sz; s++){ nxt[s] += cur[s^(1<<i)]; if ((s&(1<<i)) == 0 && i + 1 < w && (s & (1<<(i+1)))) nxt[s] += cur[s^(1<<(i+1))]; } cur = nxt; } } cout << cur[0] << endl; } }
C++ 解法, 执行用时: 192ms, 内存消耗: 584K, 提交时间: 2022-01-16 15:44:26
#include<bits/stdc++.h> using namespace std; long long f[12][2048],n,m,ins[2048]; void ps(){for(int i=0;i<1<<m;i++){bool cnt=0,ho=0;for(int j=0;j<m;j++){if(i>>j&1)ho|=cnt,cnt=0;else cnt^=1;}ins[i]=(cnt|ho)?0:1;}} void se(){ f[0][0]=1; for(int i=1;i<=n;i++)for(int j=0;j<1<<m;j++){f[i][j]=0;for(int k=0;k<1<<m;k++)if((j&k)==0&&ins[j|k])f[i][j]+=f[i-1][k];} cout<<f[n][0]<<"\n"; } int main(){ while(cin>>n>>m&&(n||m))ps(),se(); return 0; }