HDU-1693 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 }

 

你可能感兴趣的:(tree)