您的位置:首页 > 其它

poj(3254)——Corn Fields

2015-10-17 14:07 423 查看
题意:

现在有大小为M*N的方格,然后方格中0代表的是这里不能种植,1代表的是可以,然后每头牛不能和相邻的牛待在一起,然后问你有几种安排牛吃草的方案,注意,没有牛可以吃草也是算一种的。

思路:

今天刚刚学了状压dp,位运算真是巧妙啊。这里我们可以用二进制的数来代表一个状态,首先我们可以先把图用一个十进制数存下来。然后找出所有的可行方案,然后再分别判断每种状态能不能够符合条件就好了。

http://blog.csdn.net/y990041769/article/details/24658419

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define maxn 13
#define mod 100000000
const int N=13;
const int M=1<<N;
int dp
[M],mp
; //mp中存的是每一行的十进制状态;
int state[M]; //state中存的是所有符合条件的状态;
bool judge(int x){
return (x&(x<<1)); //与二进制有没有相邻的1
}
bool judge2(int i,int j){
return (mp[i]&state[j]);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int x;
scanf("%d",&x);
if(x==0){
mp[i]+=1<<(j-1); //这里是当为0的时候进行保存下来;
}
}
}
int cnt=0;
for(int i=0;i<(1<<m);i++){
if(!judge(i)){
state[cnt++]=i;
}
}
for(int i=0;i<cnt;i++){
if(!judge2(1,i)){
dp[1][i]=1;
}
}
for(int i=2;i<=n;i++){
for(int j=0;j<cnt;j++){
if(!judge2(i,j)){
for(int k=0;k<cnt;k++){
if(judge2(i-1,k)) continue;
else if(!(state[j]&state[k])){
dp[i][j]+=dp[i-1][k];
}
}
}
}
}
int ans=0;
for(int i=0;i<cnt;i++){
ans+=dp
[i];
ans=ans%mod;
}
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  状压dp