【HDOJ】【1693】Eat The Trees

插头DP

  插头dp模板题……

  这题比CDQ论文上的例题还要简单……因为不用区分左右插头(这题可以多回路,并不是一条哈密尔顿路)

  硬枚举当前位置的状态就好了>_<

  题解:http://blog.csdn.net/xymscau/article/details/6756351

 

 1 //HDU 1693
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define rep(i,n) for(int i=0;i<n;++i)
 8 #define F(i,j,n) for(int i=j;i<=n;++i)
 9 #define D(i,j,n) for(int i=j;i>=n;--i)
10 using namespace std;
11 int getint(){
12     int v=0,sign=1; char ch=getchar();
13     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
14     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
15     return v*sign;
16 }
17 /*******************template********************/
18 const int N=13;
19 typedef long long LL;
20 int mp[N][N];
21 LL dp[N][N][1<<N];
22 int n,m;
23 
24 void DP(){
25     memset(dp,0,sizeof (dp));
26     dp[0][m][0]=1;
27     F(i,1,n){//第i行 
28 //        for(int j=0;j<(1<<m);j++)
29         rep(j,(1<<m))
30             dp[i][0][(j<<1)]=dp[i-1][m][j];
31         //换行(将上一行最后一格状态放到这一行第一格,方便转移……) 
32         
33         F(k,1,m)//第k个格子 
34             rep(sta,1<<(m+1)){//枚举当前状态sta 
35                 int y=1<<k,x=1<<(k-1); 
36                 if(mp[i][k]){//如果当前格子无障碍 
37                     if( (sta&x)!=0 && (sta&y)!=0 )//如果状态为(1,1) 
38                         dp[i][k][sta]=dp[i][k-1][sta-x-y];//从(0,0)转移过来 
39                     else if( (sta&x)==0 && (sta&y)==0 )//如果状态为(0,0) 
40                         dp[i][k][sta]=dp[i][k-1][sta+x+y];//从(1,1)转移过来 
41                     else //状态为(0,1)或(1,0)则从(1,0)&&(0,1)转过来 
42                         dp[i][k][sta]=dp[i][k-1][sta^x^y]+dp[i][k-1][sta];
43                 }//如果当前格子有障碍 
44                 else
45                     if( (sta&x)==0 && (sta&y)==0)//若当前状态为(0,0) 
46                         dp[i][k][sta]=dp[i][k-1][sta];//则ans从前一格 
47                     else
48                         dp[i][k][sta]=0;
49             }
50     }
51     printf("There are %lld ways to eat the trees.\n",dp[n][m][0]);
52 }
53 int main(){
54     int T=getint(),num=0;
55     while(T--){
56         num++;
57         n=getint();m=getint();
58         F(i,1,n)
59             F(j,1,m) mp[i][j]=getint();
60         printf("Case %d: ",num);
61         DP();
62     }
63     return 0;
64 }
View Code(带注释)

 

posted @ 2015-02-04 15:50  Tunix  阅读(176)  评论(2编辑  收藏  举报