Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and can't be planted. Canny FJ knows that the cows dislike eating close to each other, so when choosing which squares to plant, he avoids choosing squares that are adjacent; no two chosen squares share an edge. He has not yet made the final choice as to which squares to plant.
Being a very open-minded man, Farmer John wants to consider all possible options for how to choose the squares for planting. He is so open-minded that he considers choosing no squares as a valid option! Please help Farmer John determine the number of ways he can choose the squares to plant.
Lines 2.. M+1: Line i+1 describes row i of the pasture with N space-separated integers indicating whether a square is fertile (1 for fertile, 0 for infertile)
2 3 1 1 1 0 1 0
9
1 2 3 4
There are four ways to plant only on one squares (1, 2, 3, or 4), three ways to plant on two squares (13, 14, or 34), 1 way to plant on three squares (134), and one way to plant on no squares. 4+3+1+1=9.
题意:Farmer John 放牧cow,有些草地上的草是不能吃的,用0表示,然后规定两头牛不能相邻放牧。问你有多少种放牧方法。
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define mod 100000000
const int maxn=13;
int dp[maxn][1<<maxn];//每个状态可以放牧方法的总数
int n, m;
int sta[maxn];//能不能放牧的状态
bool check(int x, int y)//检查同列有没有相邻的或者x的状态是否可以存在
{
if (x&y)
return false;
return true;
}
bool checkself(int x)//检查同行有没有相邻的
{
if (x&(x<<1))
return false;
return true;
}
int go()
{
int num = 1<<m;
for (int i = 0; i < num; i++)
{
if (check(i, sta[1]) && checkself(i))
dp[1][i] = 1;
}
for (int i = 2; i <= n; i++)
{
for (int j = 0; j < num; j++)
{
if (!check(j, sta[i])) //sta[i]表示i行不能存在的状态
continue;
for (int k = 0; k < num; k++)
{
if (check(k, j) && checkself(j) && checkself(k))
dp[i][j] += (dp[i-1][k]%mod);
}
}
}
int ans = 0;
for (int i = 0; i < num; i++)
{
ans += (dp[n][i]%mod);
}
return ans%mod;
}
int main()
{
int t;
while (scanf("%d %d", &n, &m) != EOF)
{
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
scanf("%d", &t);
if (!t)
{
sta[i] += (1<<(m-j));//这里对不能出现的状态做标记
}
}
}
printf("%d\n", go());
}
return 0;
}