
Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won't turn into a nightmare!
Input
Output
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.Sample Input
1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0
Sample Output
1 0 1 2 3 5 144 51205
用2进制的01表示不放还是放
<p>第i行只和i-1行有关</p><p><pre name="code" class="cpp">#include<iostream>
#include<algorithm>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define ll long long
using namespace std;
ll dp[15][1<<11]; //表示第i行为某种状态的时候(为止)已经有多少种方法数
ll n,m,tem; //n行m列,tem表示方法数
void dfs(int i,int p,int k){ //i:第几行,p:用二进制表示的当前这一行各个位置状态,k:第几列
if(k>=m){
dp[i][p]+=tem;
return;}
dfs(i,p,k+1);
if(k<=m-2&&!(p&1<<k)&&!(p&1<<k+1)) //如果该行连续两列都为0,则可以选择添加一个横砖
dfs(i,p|1<<k|1<<k+1,k+2);} //p|1<<k|1<<k+1表示把该行这两个位置置1
int main(){
while(cin>>n>>m&&n!=0&&m!=0){
memset(dp,0,sizeof(dp));
tem=1;
dfs(1,0,0);
for(int i=2;i<=n;++i){
for(int j=0;j<(1<<m);++j){
if(dp[i-1][j]>0){
tem=dp[i-1][j];
dfs(i,~j&((1<<m)-1),0);}}} //~j&((1<<m)-1)所有位置取反
cout<<dp[n][(1<<m)-1]<<endl;} //输出最后一行所有位置的数都是1的情况
return 0;
}
1120



被折叠的 条评论
为什么被折叠?



