原文链接http://www.cnblogs.com/zhouzhendong/p/8433484.html
题目传送门 - HDU1693
题意概括
多回路经过所有格子的方案数。
做法
最基础的插头dp裸题。
只要一个横向插头和一排纵向插头就可以了。
分类也很少。
插头dp -> http://www.cnblogs.com/zinthos/p/3897854.html
代码
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef unsigned long long ULL;
const int N=15,S=1<<12;
int T,n,m,f[N][N];
ULL dp[2][S];
int main(){
scanf("%d",&T);
int Case=0;
while (T--){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&f[i][j]);
memset(dp,0,sizeof dp);
int T0=1,T1=0,s=1<<(m+1);
dp[0][0]=1;
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
T0^=1,T1^=1;
memset(dp[T1],0,sizeof dp[T1]);
for (int x=0;x<s;x++){
if (!dp[T0][x])
continue;
if (!f[i][j]){
if (!(x&1)&&!((x>>j)&1))
dp[T1][x]+=dp[T0][x];
continue;
}
int L=x&1,U=(x>>j)&1;
if (L&&U)
dp[T1][x^1^(1<<j)]+=dp[T0][x];
if (L&&!U)
dp[T1][x]+=dp[T0][x],dp[T1][x^1^(1<<j)]+=dp[T0][x];
if (!L&&U)
dp[T1][x]+=dp[T0][x],dp[T1][x^1^(1<<j)]+=dp[T0][x];
if (!L&&!U)
dp[T1][x^1^(1<<j)]+=dp[T0][x];
}
}
for (int x=0;x<s;x++)
if (x&1)
dp[T1][x]=0;
}
printf("Case %d: There are %llu ways to eat the trees.\n",++Case,dp[T1][0]);
}
return 0;
}