(状压dp)洛谷P1879玉米田

洛谷P1879玉米田

思路:

第一次自己把状压dp写出来,有点激动。
dp[i][j]表示在第i层的状态j。
在预处理的时候判断下每层的合法情况。设第一层可选的状态都是1。

代码:

#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
const int N=1e6+10;
const int mod=1e9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
int n,m,a[15][15],dp[15][1<<15]={0},sta[15][1<<15],len[15]={0};
int judge(int p,int x)
{
	int i;
	for(i=1;i<=m;i++)
		if((x>>(m-i))&1==1 && a[p][i]==0)
			return 0;
	return 1;
}
void pre()
{
	int i,j;
	for(i=1;i<=n;i++)
		for(j=0;j<(1<<m);j++)
			if((((j>>1)|(j<<1))&j)==0 && judge(i,j))
				sta[i][++len[i]]=j;
	for(i=0;i<(1<<m);i++)
		for(j=1;j<=len[1];j++)
			if(sta[1][j]==i)
				dp[1][i]=1;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int i,j,k;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			cin>>a[i][j];
	pre();
	for(i=2;i<=n;i++)
		for(j=1;j<=len[i-1];j++)	
		{
			int x=sta[i-1][j];
			for(k=1;k<=len[i];k++)
			{
				int y=sta[i][k];
				if((y&x)==0)
					dp[i][y]+=dp[i-1][x];
			}
		}
	int ans=0;
	for(i=0;i<(1<<m);i++)	
		ans=(ans+dp[n][i])%mod;
	cout<<ans<<endl;
	return 0;
}

发布了78 篇原创文章 · 获赞 0 · 访问量 1403

猜你喜欢

转载自blog.csdn.net/Z7784562/article/details/103946508