POJ3254--Corn Fields

题目大意:有一个m*n的场地,1表示可以种草,0表示不可以。在草地上可以放牛,但是,两头牛不能相邻,问有多少种放牛方法(牛的数量不限,不放牛也算一种)。

 

分析:状压DP。状态:dp[i][j]表示第i行第j种状态的方法数。

状态转移方程,慢慢分析。

首先,我们判断一行有多少种放牛方法,因为1不能相邻,且最多只有12列,所以总数不会超过600。接着,判断哪些方法与第一行场地不矛盾,由于只要存在一个位置矛盾,那么整行就无效,所以,我们在存储场地时,反过来存,然后,用按位与操作,就可以接着这个存在性问题了。初始化的问题都解决了。下面就进入状态转移的过程。

从第二行开始枚举,同样判断哪些方法与第二行场地不矛盾,然后判断哪些状态与前一行不矛盾,且与这一行也不矛盾。那么这样子的状态就是可行的。dp[i][j]=dp[i][j]+dp[i-1][k]。


代码:

#include 
#include 
#include 
using namespace std;

#define MOD 100000000

int dp[15][600];
int state[600];
int g[15];
int m, n;
int tot;

bool ok(int x) {
    if(x & x<<1) return false;
    else return true;
}

void init() {
    tot = 0;
    for(int i = 0; i < 1<


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