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\n",++ca,ans>0?"Tom200":"Jerry404");

90     }

91     return 0;

92 }
View Code

 

 

 

你可能感兴趣的:(game)