题目链接:http://poj.org/problem?id=3254
与POJ1185类似,不过这里每一行的状态只收前一行影响,所以用 f[i][t] 表示第 i 行状态为 stk[t] 时的总方案数,那么根据加法原理,f[i][t] = f[[i][t] + f[i-1][j],j 表示第 i-1 行所有合法的切与状态 stk[t] 不相邻的状态,记得取模。
还有就是对每一行的状态判断是否合适,就是不能在贫瘠的草场放牛。(判断的状态与要判断的那一行一定要看清,不然是不会过的,不要问我是怎么知道的)
#include<iostream>
using namespace std;
int stk[1000];
int dp[15][1000];
int cur[15];
int tot;
bool legal(int x)
{
if (x & (x<<1)) return false;
return true;
}
void init(int n)
{
tot = 0;
for (int i=0; i<=(1<<n)-1; i++)
if (legal(i)) stk[++tot] = i;
}
bool fit(int s, int k)
{
if (s & cur[k]) return false;
return true;
}
int main()
{
int n, m;
cin>>n>>m;
for (int i=1; i<=n; i++)
{
cur[i] = 0;
for (int j=1; j<=m; j++)
{
int x;
cin>>x;
x = (!x);
cur[i] = cur[i]*2 + x;
}
}
init(m);
for (int i=1; i<=tot; i++)
{
if (!fit(stk[i],1)) continue;
dp[1][i] = 1;
}
for (int i=2; i<=n; i++)
for (int t=1; t<=tot; t++)
{
if (!fit(stk[t], i)) continue;
for (int j=1; j<=tot; j++)
{
if (!fit(stk[j],i-1)) continue;
if (stk[t] & stk[j]) continue;
dp[i][t] = (dp[i][t] + dp[i-1][j]) % 100000000;
}
}
int ans = 0;
for (int i=1; i<=tot; i++)
{
if (!fit(stk[i], n)) continue;
ans = (ans + dp[n][i]) % 100000000;
}
cout<<ans<<endl;
return 0;
}