**POJ3254 Corn Fields ACM解题报告(状压dp)

来源:互联网 发布:苹果4s怎么升级4g网络 编辑:程序博客网 时间:2024/05/21 18:43

人生第一个状压dp,虽然是看了题解艰难完成的,也算是把这题搞懂了,以前虽然稍微了解过状压dp,但是没想到实现起来也这么难。

这题就是给你的图中出现1的位置可以放牛,但是每个牛不能相邻(横竖相邻),一般状压的数据范围会比较小,然后就是用位运算把每行的情况都存起来。

这题首先要把1不会出现相邻的情况全部打表算出来,存储在state数组中(这个情况有377种)。

然后如果state[i]的每一个1的位置,在当前第j行的位置都是1,就是说第j行满足第i种情况,在dp[j][i]中存储这行这种情况的个数,如何来判断state[i]中的每个1在第j行中也是1呢,看了人家的题解发现真是精妙,将第j行的0出现的位置用位运算存起来,如果state[i]&a[j]为正,就是state[i]中的1在第j行的0的位置出现,那么肯定不满足这种情况了,如果运算结果位0,那么就是state[i]的1都出现在第j行的1的位置。

状态转移方程是dp(i,j)=sigma dp(i-1,k)state[j]&state[k]=0。(i表示行,j,k表示state中的第几种情况,然后这两种情况与运算等于0,就是竖直方向不能出现相邻)。

状压dp对于我来说还是很陌生啊,我得再搞明白几个题。

#include<iostream>#include<cstdio>#include<cctype>#include<cstdlib>#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<vector>#include<queue>#include<map>#include<set>#include<sstream>#include<stack>using namespace std;#define MAX 105typedef long long LL;const double pi=3.141592653589793;const int INF=1e9;const double inf=1e20;const double eps=1e-6;int dp[15][400];int m,n,top;int state[400];//所有1不相邻的情况先存起来int a[15];//每行的情况(把0出现的位置存起来,和state中的情况进行位运算,如果非0,就是这行的情况不满足state中的这个情况)bool ok(int x){//计算有多少种1不相邻的状态if(x&x<<1) return false;return true;}void init(){int total=1<<n;top=0;for(int i=0;i<total;i++){if(ok(i)) state[top++]=i;}}bool fit(int x,int y){if(x&a[y]) return 0;//判断这一行的状态是否包含state中满足条件的状态return 1;}int main(){    scanf("%d%d",&m,&n);    init();    memset(dp,0,sizeof(dp));    for(int i=0;i<m;i++){    for(int j=0;j<n;j++){    int x;    scanf("%d",&x);    if(x==0) a[i]+=(1<<j);//将0储存,因为需要state中的情况中的1完全包含于这一行的1,才算满足情况,将0储存做&运算比较方便    }    }    for(int i=0;i<top;i++){    if(fit(state[i],0)) dp[0][i]=1;//第一行的情况    }    for(int i=1;i<m;i++){    for(int k=0;k<top;k++){    if(fit(state[k],i)){//第i行满足的情况    for(int j=0;j<top;j++){    if(fit(state[j],i-1)){//上一行满足的情况    if(state[k]&state[j]) continue;//竖直方向不能有相邻的1    else dp[i][k]=(dp[i][k]+dp[i-1][j])%100000000;    }    }    }    }    }    int ans=0;    for(int i=0;i<top;i++) ans=(ans+dp[m-1][i])%100000000;    printf("%d\n",ans);    return 0;}


0 0
原创粉丝点击