poj3254 状态压缩dp

来源:互联网 发布:8月外贸数据 编辑:程序博客网 时间:2024/05/16 12:58

先将横排压缩,在比较竖排。

#include <cstdio>#include <cstring>#define mod 100000000using namespace std;int a[20][20];int num[20][1<<12];int dp[20][1<<12];int n,m;int check(int i,int j){    for(int k=0; k<m; k++)    {        if((j&(1<<k))&&!a[i][k])            return 0;        if(k>0)        {            if(((j&(1<<k))&&(j&(1<<(k-1)))))                return 0;        }    }    return 1;}int main(){    while(~scanf("%d%d",&n,&m))    {        for(int i=0; i<n; i++)            for(int j=0; j<m; j++)                scanf("%d",&a[i][j]);        for(int i=0; i<n; i++)        {            num[i][0]=0;            for(int j=0; j<(1<<m); j++)            {                if(check(i,j))                {                    num[i][0]++;                    num[i][num[i][0]]=j;                }            }        }memset(dp,0,sizeof(dp));        for(int i=1; i<=num[0][0]; i++)            dp[0][num[0][i]]=1;        for(int i=1; i<n; i++)        {            for(int j=1; j<=num[i][0]; j++)            {                for(int k=1; k<=num[i-1][0]; k++)                {                    if(((num[i][j])&(num[i-1][k]))==0)                    {                        dp[i][num[i][j]]+=dp[i-1][num[i-1][k]];                        dp[i][num[i][j]]%=mod;                    }                }            }        }        /*for(int i=0;i<n;i++)        {            for(int j=0;j<(1<<m);j++)            {                printf("%d ",dp[i][j]);            }            printf("\n");        }*/        int ans=0;        for(int i=1; i<=num[n-1][0]; i++)        {            ans+=dp[n-1][num[n-1][i]];            ans%=mod;        }        printf("%d\n",ans);    }}

0 0
原创粉丝点击