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 }