原文链接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. ",++Case,dp[T1][0]); } return 0; }