poj3254 (压状dp入门)

题目大意:农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的(用1标记),农夫可以在这些格子里放牛,其他格子则不能放牛(用0标记),并且要求不可以使相邻格子都有牛。现在输入数据给出这块地的大小及可否放牧的情况,求该农夫有多少种放牧方案可以选择(注意:任何格子都不放也是一种选择,不要忘记考虑!


解题思路:以样例数据第一行为例,三个格子都可以放牧,即每个格子都可以选择放,或不放。再考虑附加条件“相邻格子不可同时放牧”,那么我们可以列出单看第一行时的所有可行状态如下(1代表放牧,0代表不放牧)


代码:

#include<cstdio>
#include<algorithm>
using namespace std;
#define mod 100000000
int a[20];
int dp[13][1<<13];
int line(int x,int y){
	if((a[x]&y)!=y)return 0;
	if((y&(y<<1))!=0)return 0;
	return 1;
}

int main(){
	int n,m;
	while(~scanf("%d%d",&n,&m)){
		for(int i=1;i<=n;i++){
			a[i]=0;
			for(int j=1;j<=m;j++){
				int t;
				scanf("%d",&t);
				a[i]=(a[i]<<1)+t;
			}
		}
		memset(dp,0,sizeof(dp));
		dp[0][0]=1;
		for(int i=1;i<=n;i++){
			for(int j=0;j<(1<<m);j++){
				if(line(i,j)==0)continue;
				for(int k=0;k<(1<<m);k++){
					if((j&k)==0){
						dp[i][j]=dp[i][j]+dp[i-1][k];
						dp[i][j]%=mod;
					}
				}
			}
		}
		int ans=0;
		for(int i=0;i<(1<<m);i++){
			ans=(ans+dp[n][i])%mod;
		}
		printf("%d\n",ans);
	}
}

猜你喜欢

转载自blog.csdn.net/running_acmer/article/details/80586350
今日推荐