POJ-2411-Mondriaan's Dream

书上动态规划的状态压缩的练习题,是求w*h的长方形有放1*2和2*1的长方形,最多有多少种方法。

思路:

1、用状态压缩当前层的状态。

2、首先可以算出第一层的所有的合法状态,然后依次向后计算~

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=2050;
int h,w,m,sz;
long long dp[11][maxn],s[maxn];
void DFS(int index,int val,int cnt0)
{
    if(index==w)
    {
	if(cnt0&1)
	    return;
	s[sz++]=val;
	return;
    }
    if(cnt0&1)
	DFS(index+1,val,cnt0+1);
    else
    {
	DFS(index+1,val|(1<<index),cnt0);
	DFS(index+1,val,cnt0+1);
    }
}
void solve()
{
    DFS(0,0,0);
    memset(dp,0,sizeof(dp));
    for(int i=0;i<sz;i++)
	dp[0][s[i]]=1;
    for(int i=1;i<h;i++)
	for(int j=0;j<sz;j++)
	    for(int k=0;k<=m;k++)
	    {
		if(!dp[i-1][k])
		    continue;
		if((k&(~s[j]))!=0)
		    continue;
		dp[i][s[j]-k]+=dp[i-1][k];
	    }
    printf("%I64d\n",dp[h-1][0]);
}
int main()
{
    while(scanf("%d%d",&h,&w)&&(h+w))
    {
	if((h*w)&1)
	{
	    printf("0\n");
	    continue;
	}
	m=(1<<w)-1;
	sz=0;
	solve();
    }
    return 0;
}


你可能感兴趣的:(dp,状态压缩)