状压dp练习

来源:互联网 发布:淘宝联盟客服热线 编辑:程序博客网 时间:2024/06/08 00:28
  • POJ-3254

主要参考题解链接

#include <cstdio>#include <cstring>#include <vector>#include <queue>#include <iostream>#include <cmath>#include <vector>#include <algorithm>#include <map>using namespace std;#define DEBUGconst int maxn=12+5,maxv=26,INF=0x3f3f3f3f,mod=100000000;int buf[maxn][maxn],m,n,state[380],d[maxn][380],rem[maxn];//12对应377种状态bool ok(int x){    if(x&(x<<1))return false;    return true;}bool fit(int a,int b){    if(a&~b)return false;    else return true;}int main(){#ifdef DEBUG    freopen("in.txt", "r", stdin);    freopen("out.txt", "w", stdout);#endif    while(cin>>n>>m){        memset(rem,0,sizeof(rem));        for(int i=0;i<n;i++){            rem[i]=0;            for(int j=0;j<m;j++){                cin>>buf[i][j];                if(buf[i][j]==1)                    rem[i]+=(1<<m-1-j);            }        }        int total=1<<m,cnt=0;        // d[0][0]=1;d[0][1]=1;        // for(int i=1;i<n;i++){d[i][1]=d[i-1][0];d[i][0]=d[i-1][1]+d[i-1][0];}        // for(int i=0;i<n;i++)printf("%d \n",d[i][1]+d[i][0]);        for(int i=0;i<total;i++){            if(ok(i))state[cnt++]=i;        }        memset(d,0,sizeof(d));        for(int i=0;i<n;i++){            if(i==0){                for(int j=0;j<cnt;j++){                    if(fit(state[j],rem[i])){d[0][j]=1;}                }                continue;            }            for(int j=0;j<cnt;j++){                if(!fit(state[j],rem[i]))continue;                for(int k=0;k<cnt;k++){                    if(!fit(state[k],rem[i-1]))continue;                    if(state[k]&state[j])continue;                    d[i][j]=(d[i][j]+d[i-1][k])%mod;                }            }        }        int ans=0;        for(int i=0;i<cnt;i++){            ans=(ans+d[n-1][i])%mod;        }        printf("%d\n",ans);    }#ifdef DEBUG    fclose(stdin);    fclose(stdout);#endif    return 0;}
原创粉丝点击