• poj 1085 Triangle War 博弈论+记忆化搜索


    思路:总共有18条边,9个三角形。

    极大极小化搜索+剪枝比较慢,所以用记忆化搜索!!

    用state存放当前的加边后的状态,并判断是否构成三角形,找出最优解。

    代码如下:

     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<<25
     9 using namespace std;
    10 int edge[][2]={{1,2},{1,3},{2,3},{2,4},{2,5},{3,5},{3,6},{4,5},{5,6},{4,7},{4,8},{5,8},{5,9},{6,9},{6,10}
    11 ,{7,8},{8,9},{9,10}};
    12 int tri[][3]={{0,1,2},{3,4,7},{2,4,5},{5,6,8},{9,10,15},{7,10,11},{11,12,16},{8,12,13},{13,14,17}};
    13 int p[18],dp[1<<18];
    14 int cal(int state,int e)
    15 {
    16       int ans=0;
    17       for(int i=0;i<9;i++){
    18             bool flag=0;
    19             for(int j=0;j<3;j++) //判断边e是否在这个三角形中
    20                   if(e==tri[i][j]) flag=true;
    21             if(flag){ //e在这个三角形中
    22                   for(int j=0;j<3;j++){
    23                         if(!(p[tri[i][j]]&state||e==tri[i][j])){ //如果满足条件说明tri[i][j]这条边不存在且e也不是这条边
    24                               ans--;break;                               //也就是不能构成三角形,否则能构成
    25                         }
    26                   }
    27                   ans++;
    28             }
    29       }
    30       return ans;
    31 }
    32 int dfs(int state)
    33 {
    34       if(dp[state]!=-inf) return dp[state];
    35       int ans=-inf;
    36       for(int i=0;i<18;i++){
    37             if(!(state&p[i])){
    38                   int tt=cal(state,i);
    39                   if(tt) tt+=dfs(state|p[i]);
    40                   else tt-=dfs(state|p[i]);
    41                   ans=max(ans,tt);
    42             }
    43       }
    44       return dp[state]=ans;
    45 }
    46 int main()
    47 {
    48       //freopen("1.txt","r",stdin);
    49     int t,u,v,ca=0,m;
    50     p[0]=1;
    51     for(int i=1;i<18;i++) p[i]=p[i-1]*2;
    52     for(int i=0;i<(1<<18);i++) dp[i]=-inf;
    53     dp[(1<<18)-1]=0;
    54     scanf("%d",&t);
    55     while(t--){
    56             scanf("%d",&m);
    57             int m0=0,m1=0,tt=0,state=0,side=0;
    58             while(m--){
    59                   scanf("%d%d",&u,&v);
    60                   for(int i=0;i<18;i++)
    61                         if(edge[i][0]==u&&edge[i][1]==v){
    62                               tt=cal(state,i);
    63                               state|=p[i];
    64                               side==0?m0+=tt:m1+=tt;
    65                               side++;
    66                               if(tt) side++;
    67                               side%=2;
    68                               break;
    69                         }
    70             }
    71             int ans=m0-m1;
    72             if(side==0) ans+=dfs(state);
    73             else ans-=dfs(state);
    74             printf("Game %d: %s
    ",++ca,ans>0?"A wins.":"B wins.");
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    docker
    Flask
    JavaScirpt
    记录片- 走进肯德基 :十亿美元鸡肉店(2015)
    法正(3):扫黑
    法正(2):法雄
    法正(1):年表
    三国皇帝的寡妇秘史(2)
    三国皇帝的寡妇秘史(1)
    程序员的人性思考(下)
  • 原文地址:https://www.cnblogs.com/xin-hua/p/3327988.html
Copyright © 2020-2023  润新知