hdu 4753 Fishhead’s Little Game 博弈论+记忆化搜索

思路:状态最多有2^12,采用记忆化搜索!!

代码如下:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<vector>
 8 #define inf 1<<30
 9 using namespace std;
10 int edge[][2]={{1,2},{2,3},{3,4},{1,5},{2,6},{3,7},{4,8},{5,6},{6,7},{7,8},{5,9},
11 {6,10},{7,11},{8,12},{9,10},{10,11},{11,12},{9,13},{10,14},{11,15},{12,16},{13,14},
12 {14,15},{15,16}};
13 int tri[][4]={{0,3,4,7},{1,4,5,8},{2,5,6,9},{7,10,11,14},{8,11,12,15},
14 {9,12,13,16},{14,17,18,21},{15,18,19,22},{16,19,20,23}};
15 int p[25],index[25],cnt;
16 int dp[1<<12];
17 int cal(int state,int e)
18 {
19       int ans=0,t=0;
20       for(int i=0;i<9;i++){
21             bool flag=0;
22             for(int j=0;j<4;j++)
23                   if(e==tri[i][j]){
24                         flag=true;
25                         break;
26                   }
27             if(flag){
28                   t++;
29                   for(int j=0;j<4;j++){
30                         if(!(p[tri[i][j]]&state||e==tri[i][j])){
31                               ans--;break;
32                         }
33                   }
34                   ans++;
35             }
36             if(t==2) break;
37       }
38       return ans;
39 }
40 int dfs(int state,int now)
41 {
42       if(dp[now]!=-inf) return dp[now];
43       int ans=-inf;
44       for(int i=0;i<cnt;i++){
45             if(!(now&p[i])){
46                   int tt=cal(state,index[i]);
47                   tt-=dfs(state|p[index[i]],now|p[i]);
48                   ans=max(ans,tt);
49             }
50       }
51       return dp[now]=ans;
52 }
53 int main()
54 {
55     int t,u,v,ca=0,m;
56     bool vis[25];
57     p[0]=1;
58     for(int i=1;i<=24;i++) p[i]=p[i-1]*2;
59     scanf("%d",&t);
60     while(t--){
61             scanf("%d",&m);
62             int m0=0,m1=0,tt=0,state=0,side=0;
63             memset(vis,0,sizeof(vis));
64             while(m--){
65                   scanf("%d%d",&u,&v);
66                   if(u>v) swap(u,v);
67                   for(int i=0;i<24;i++)
68                         if(edge[i][0]==u&&edge[i][1]==v){
69                               tt=cal(state,i);
70                               vis[i]=1;
71                               state|=p[i];
72                               side==0?m0+=tt:m1+=tt;
73                               side++;
74                               side%=2;
75                               break;
76                         }
77             }
78             cnt=0;
79             for(int i=0;i<24;i++){
80                 if(!vis[i]){
81                     index[cnt++]=i;
82                 }
83             }
84             for(int i=0;i<(1<<cnt);i++) dp[i]=-inf;
85             dp[(1<<cnt)-1]=0;
86             int ans=m0-m1;
87             if(side==0) ans+=dfs(state,0);
88             else ans-=dfs(state,0);
89             printf("Case #%d: %s
",++ca,ans>0?"Tom200":"Jerry404");
90     }
91     return 0;
92 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3331754.html