【USACO06NOV】玉米田Corn Fields(状态压缩dp)

首先这题可以用状态压缩来表示一行的放置情况。为了节省空间和时间可以输入时直接把N和M减去一。

设f[i][S]表示第i行放置情况为S时的方案数,那么最后答案就是f[N]可行状态的和。

我们枚举每一行,每次做如下的事情:

1,得到下一行的所有可行情况, 存入数组。

2,以当前行的可行情况去更新下一行的可行情况。

3,交换上下行, 下一行作为当前行重复此操作。

4,第0行不做下一行,第N行不做当前行。

更新操作:枚举当前行i的状态S,下一行i+1可行状态T,如果两个状态没有交集,下一行的方案数f[i+1][T]加上f[i][S]。

代码有注释。

#include
using namespace std;
const int MAXN=12;
const int mod=100000000;
int N,M,mp[MAXN][MAXN],state[2][1024],tot[2],f[MAXN][1024];

void getstate(int x,int side)
{
	tot[side]=0;  //计数归0 
	int i,S,no=0,flag;
	for(i=0;i<=M;i++) if(mp[x][i]==0) no+=(1<>N>>M;
	N-=1; M-=1;
	for(i=0;i<=N;i++)
		for(j=0;j<=M;j++)
			cin>>mp[i][j];
	
	int ans=0,up=0,down=1; //up当前行,down下一行 
	getstate(0,up);
	for(j=1;j<=tot[up];j++) f[0][state[up][j]]=1; //第0行可行的状态方案均为1 
	
	for(i=0;i=mod) ans-=mod;
	}
	cout<

 

你可能感兴趣的:(动态规划)