POJ --3254--Corn Fields--状态DP

33 篇文章 2 订阅

状态DP上手~

和炮兵阵地很相似的道理,会了炮兵阵地就会这个了。

同样的思路,当前行的状态由上一行的可行状态整合而来,具体思路见代码

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 20
#define dbug1
#define M 100000000
using namespace std;
const int maxStatu=1<<13;
int bmp[maxn][maxn];
int sp[maxn];
int n,m;
int sc,st[maxStatu];
int dp[maxn][maxStatu];
void init()
{
	memset(dp,0,sizeof(sp));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&bmp[i][j]);
			sp[i]|=bmp[i][j]*(1<<(m-j));
		}
	}
	sc=0;
	int nms=1<<m;
	#ifdef dbug
	printf("this is status:\n");
	#endif
	for(int i=0;i<nms;i++)
	{
		if(i&(i<<1))continue;
		st[sc++]=i;
		#ifdef dbug
		printf("%d ",i);
		#endif
	}
	#ifdef dbug
		printf("\n");
	#endif
}
void solve()
{
	memset(dp,0,sizeof(dp));
	for(int i=0;i<sc;i++)
	{
		if((sp[1]&st[i])!=st[i])continue;
		dp[1][st[i]]=1;
	}
	for(int i=2;i<=n;i++)
	{
		for(int j=0;j<sc;j++)  //枚举第 i 行状态  
		{
			if((st[j]&sp[i])!=st[j])continue;	//判断第  i 能否放置状态 st[j] 
			
			for(int k=0;k<sc;k++)  //枚举第 i-1 行状态 
			{
				if(st[k]&st[j])continue;
				#ifdef dbug
				printf("st1---%d st2--%d\n",st[j],st[k]);
				#endif
				dp[i][st[j]]+=dp[i-1][st[k]];
				dp[i][st[j]]%=M; 
			}
		}
	}
	int ans=0;
	for(int i=0;i<sc;i++)
	{
		ans+=dp[n][st[i]];
		ans%=M;
	}
	printf("%d\n",ans);
}


int main()
{
	init();
	solve();
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值