poj 3254 Corn Fields 状态压缩dp

题意:

给一块m行n列的土地,有一些格可以种树,另外一些不可以,树不能相邻,问一共有多少种种法。

分析:

从后往前种,子问题向父问题扩展,当种到某一格时只有他和他后面的n-1个格子的情况对它有影响,故对这n个格子进行编码为状态S,表示种完(多米诺骨牌那题是放置前,注意区别,都可行)这n个格子的状态。父问题由稍小子问题逐步解决,正是动态规划的思想。

代码:

//poj 3254
//sep9
#include <iostream>
using namespace std;
const int maxN=14;
const int mod=100000000;
int land[maxN][maxN];
int dp[2][1<<maxN];
int m,n;

int main()
{
	scanf("%d%d",&m,&n);
	int i,j,used;
	for(i=0;i<m;++i)
		for(j=0;j<n;++j)
			scanf("%d",&land[i][j]);	
	int *cur=dp[0],*nxt=dp[1];
	cur[0]=1;
	for(i=m-1;i>=0;--i)
		for(j=n-1;j>=0;--j){
			for(used=0;used<1<<n;++used){
				if(land[i][j]==0){
					if(used>>j&1)
						nxt[used]=0;
					else{
						nxt[used]=cur[used];
						nxt[used]+=cur[used|(1<<j)];
						nxt[used]%=mod;
					}
				}
				else{
					int res=0;
					if((used>>j&1)&&(used>>(j+1)&1)){
						res=0;
					}else if(!(used>>j&1)&&(used>>(j+1)&1)){
						res=cur[used];
						res+=cur[used|(1<<j)];						
					}else if((used>>j&1)&&!(used>>(j+1)&1)){
						res=cur[used&(~(1<<j))];
					}else if(!(used>>j&1)&&!(used>>(j+1)&1)){
						res=cur[used];
						res+=cur[used|(1<<j)];			
					}
					nxt[used]=res%mod;
				}	
			} 
			swap(cur,nxt);
		}
	int sum=0;
	for(int i=0;i<1<<n;++i){
		sum+=cur[i];
		sum%=mod;
	}
	printf("%d",sum);
	return 0;	
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值