hdu 1159 最长公共子序列
zju 3209 学习dancing links

poj 2411 骨牌覆盖 dp

scturtle posted @ 2010年10月18日 22:43 in algorithm , 2569 阅读

状态压缩的dp,强大的discuss.

如果是横着的就定义11,如果竖着的定义为竖着的01,这样按行dp只需要考虑两件事儿,当前行&上一行,是不是全为1,不是说明竖着有空(不可能出现竖着的00),另一个要检查当前行里有没有横放的,但为奇数的1 

	#include <cstdio>  
#include <cstring>  
int n,m;
int full;
long long dp[12][1<<11];

bool fit1(int j)
{
    int bits=0;
    while(j)
    {
        if(j&1) ++bits;
        else
        {
            if(bits&1) return 0;
            else bits=0;
        }
        j>>=1;
    }
    if(bits&1) return 0;
    return 1;
}
bool fit2(int j,int k)
{
    if((j|k)!=full) return 0;
    return fit1(j&k);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    int i,j,k;
    while(scanf("%d%d",&n,&m),n)
    {
        if(n&m&1) {puts("0");continue;}
        full=(1<<m)-1;
        memset(dp,0,sizeof(dp));
        for(j=0;j<=full;j++)
            if(fit1(j))
                dp[1][j]=1;
        for(i=2;i<=n;i++)
        {
            for(j=0;j<=full;j++)
                for(k=0;k<=full;k++)
                    if(fit2(j,k)) dp[i][j]+=dp[i-1][k];
        }
        printf("%lld\n",dp[n][full]);
    }
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter