HDU1693 Eat the Trees 插头DP

  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1693

  插头DP的入门题,属于轮廓动态规划一类,推荐看《基于连通性状态压缩的动态规划问题》,陈丹琦写的,Orz女神...

 1 //STATUS:C++_AC_0MS_272KB
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<string>
 8 #include<algorithm>
 9 #include<vector>
10 #include<queue>
11 #include<stack>
12 #include<map>
13 using namespace std;
14 #define LL __int64
15 #define pii pair<int,int>
16 #define Max(a,b) ((a)>(b)?(a):(b))
17 #define Min(a,b) ((a)<(b)?(a):(b))
18 #define mem(a,b) memset(a,b,sizeof(a))
19 #define lson l,mid,rt<<1
20 #define rson mid+1,r,rt<<1|1
21 const int N=12,M=100000,INF=0x3f3f3f3f,MOD=100000000;
22 const double DNF=100000000000;
23 
24 int ma[N][N];
25 LL f[2][1<<N];
26 int T,n,m;
27 
28 int main()
29 {
30  //   freopen("in.txt","r",stdin);
31     int i,j,k,x,y,up,icase=0,p;
32     scanf("%d",&T);
33     while(T--)
34     {
35         mem(f,0);
36         scanf("%d%d",&n,&m);
37         for(i=0;i<n;i++)
38             for(j=0;j<m;j++)
39                 scanf("%d",&ma[i][j]);
40         f[0][0]=p=1;
41         up=1<<(m+1);
42         for(i=0;i<n;i++,mem(f[p=!p],0)){
43             for(j=0;j<m;j++,mem(f[p=!p],0)){
44                 x=1<<j;
45                 y=1<<(j+1);
46                 for(k=0;k<up;k++){
47                     if(ma[i][j]){
48                         f[p][k^x^y]+=f[!p][k];
49                         if((k&x) && (k&y))continue;
50                         if((k&x)^(k&y))f[p][k]+=f[!p][k];
51                     }
52                     else if(!(k&x) && !(k&y)){
53                         f[p][k]+=f[!p][k];
54                     }
55                 }
56             }
57             for(j=0;j<(1<<m);j++)f[p][j<<1]=f[!p][j];
58         }
59 
60         printf("Case %d: There are %I64d ways to eat the trees.\n",++icase,f[!p][0]);
61     }
62     return 0;
63 }
原文地址:https://www.cnblogs.com/zhsl/p/2988015.html