2 6 3 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 2 4 1 1 1 1 1 1 1 1
Case 1: There are 3 ways to eat the trees. Case 2: There are 2 ways to eat the trees.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <iomanip>
#define INF 99999999
typedef __int64 LL;
using namespace std;
const int MAX=(1<<12)+10;
int n,m;
int mp[12][12];
LL dp[12][12][MAX];
void DP(){
memset(dp,0,sizeof dp);
dp[0][m][0]=1;
int bit=1<<(m+1);
for(int i=1;i<=n;++i){
for(int k=0;k<(bit>>1);++k){//这里bit>>1是上一行最后一个插头肯定为0才行
dp[i][0][k<<1]=dp[i-1][m][k];//初始化本行决策到0格时的情况
}
for(int j=1;j<=m;++j){//决策到第j格
for(int k=0;k<bit;++k){//所有插头的情况
int x=1<<(j-1);//第j个
int y=1<<j;//第j+1个
if(mp[i][j]){//该方格允许有插头
dp[i][j][k]+=dp[i][j-1][k^x^y];//含有两个插头和不含有插头和含有一个插头的一种情况的综合
if((k&x) && (k&y))continue;
if(!(k&x) && !(k&y))continue;
dp[i][j][k]+=dp[i][j-1][k];//如果只含有一个插头则前一个决策相同的情况可以到达本情况
}else{
if(!(k&x) && !(k&y))dp[i][j][k]=dp[i][j-1][k];
else dp[i][j][k]=0;
}
}
}
}
}
int main(){
int t,num=0;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
scanf("%d",&mp[i][j]);
}
}
DP();
printf("Case %d: There are %I64d ways to eat the trees.\n",++num,dp[n][m][0]);
}
return 0;
}
原文:http://blog.csdn.net/xingyeyongheng/article/details/24272265