Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 11810 | Accepted: 6866 |
Description
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
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
題意:給你n*m的地板,1*2的地板磚,問將地板鋪滿的方案數
解題思路:剛剛接觸輪廓線dp,這題是比較經典的,1*2的地板磚可以橫放,豎放,還可以不放,我們只需分三種情況討論他的輪廓線狀態,詳細分析參見大白書。
代碼:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL dp[2][1<<11];
int m;
void update(int t,int a,int b)
{
if(b&(1<<m))
dp[t][b^(1<<m)]+=dp[1-t][a];
}
int main()
{
int n;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)break;
int t=0;
memset(dp,0,sizeof(dp));
dp[0][(1<<m)-1]=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
t=1-t;
memset(dp[t],0,sizeof(dp[t]));
for(int k=0;k<(1<<m);k++)
{
if(!dp[1-t][k])continue;
//bufang
update(t,k,k<<1);
//shufang
if(i&&!((1<<m-1)&k))
update(t,k,(k<<1)^1^(1<<m));
//hengfang
if(j&&!(k&1))
update(t,k,(k<<1)^3);
}
}
}
printf("%lld\n",dp[t][(1<<m)-1]);
}
return 0;
}