zoukankan      html  css  js  c++  java
  • CCF CSP认证 201803-4 棋局评估 (dp/α-β剪枝) (100分)

    经典的双人非对称零和博弈,对于Alice来说,肯定取后继状态中得分最高的一个,对于Bob来说,肯定取得分最低的一个,记忆化搜索即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1e5+10,inf=0x3f3f3f3f,mod=998244353;
     5 unordered_map<ll,int> dp;
     6 int a[4][4],p[4][4];
     7 ll enc() {
     8     ll S=0;
     9     for(int i=1; i<=3; ++i)
    10         for(int j=1; j<=3; ++j)
    11             S|=(ll)a[i][j]<<p[i][j];
    12     return S;
    13 }
    14 bool win(int f) {
    15     for(int i=1; i<=3; ++i) {
    16         if(a[i][1]==f&&a[i][2]==f&&a[i][3]==f)return 1;
    17         if(a[1][i]==f&&a[2][i]==f&&a[3][i]==f)return 1;
    18     }
    19     if(a[1][1]==f&&a[2][2]==f&&a[3][3]==f)return 1;
    20     if(a[1][3]==f&&a[2][2]==f&&a[3][1]==f)return 1;
    21     return 0;
    22 }
    23 int cnt() {
    24     int ret=0;
    25     for(int i=1; i<=3; ++i)
    26         for(int j=1; j<=3; ++j)
    27             if(!a[i][j])ret++;
    28     return ret;
    29 }
    30 int dfs(ll S,int f) {
    31     if(dp.count(S))return dp[S];
    32     int& ret=dp[S];
    33     if(win(1))return ret=cnt()+1;
    34     if(win(2))return ret=-(cnt()+1);
    35     if(cnt()==0)return ret=0;
    36     ret=f==1?~inf:inf;
    37     for(int i=1; i<=3; ++i)
    38         for(int j=1; j<=3; ++j)
    39             if(!a[i][j]) {
    40                 a[i][j]=f;
    41                 if(f==1)ret=max(ret,dfs(S|(f<<p[i][j]),f^3));
    42                 else if(f==2)ret=min(ret,dfs(S|(f<<p[i][j]),f^3));
    43                 a[i][j]=0;
    44             }
    45     return ret;
    46 }
    47 
    48 int main() {
    49     for(int i=1,now=0; i<=3; ++i)
    50         for(int j=1; j<=3; ++j)
    51             p[i][j]=now,now+=2;
    52     int _;
    53     for(scanf("%d",&_); _--;) {
    54         for(int i=1; i<=3; ++i)
    55             for(int j=1; j<=3; ++j)
    56                 scanf("%d",&a[i][j]);
    57         printf("%d
    ",dfs(enc(),cnt()&1?1:2));
    58     }
    59     return 0;
    60 }

     也可以使用α-β剪枝,无需记忆化搜索:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1e5+10,inf=0x3f3f3f3f,mod=998244353;
     5 int a[4][4];
     6 bool win(int f) {
     7     for(int i=1; i<=3; ++i) {
     8         if(a[i][1]==f&&a[i][2]==f&&a[i][3]==f)return 1;
     9         if(a[1][i]==f&&a[2][i]==f&&a[3][i]==f)return 1;
    10     }
    11     if(a[1][1]==f&&a[2][2]==f&&a[3][3]==f)return 1;
    12     if(a[1][3]==f&&a[2][2]==f&&a[3][1]==f)return 1;
    13     return 0;
    14 }
    15 int cnt() {
    16     int ret=0;
    17     for(int i=1; i<=3; ++i)
    18         for(int j=1; j<=3; ++j)
    19             if(!a[i][j])ret++;
    20     return ret;
    21 }
    22 int dfs(int f,int alpha,int beta) {
    23     if(win(1))return cnt()+1;
    24     if(win(2))return -(cnt()+1);
    25     if(cnt()==0)return 0;
    26     for(int i=1; i<=3; ++i)
    27         for(int j=1; j<=3; ++j)
    28             if(!a[i][j]) {
    29                 a[i][j]=f;
    30                 int t=dfs(f^3,alpha,beta);
    31                 if(f==1)alpha=max(alpha,t);
    32                 else if(f==2)beta=min(beta,t);
    33                 a[i][j]=0;
    34                 if(beta<=alpha)break;
    35             }
    36     return f==1?alpha:beta;
    37 }
    38 
    39 int main() {
    40     int _;
    41     for(scanf("%d",&_); _--;) {
    42         for(int i=1; i<=3; ++i)
    43             for(int j=1; j<=3; ++j)
    44                 scanf("%d",&a[i][j]);
    45         int f=cnt()&1?1:2;
    46         int ans=f==1?dfs(f,~inf,inf):dfs(f,inf,~inf);
    47         printf("%d
    ",ans);
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    关于sqlserver2008 bcp根据数据表导出xml格式文件的小记
    关于SQL SERVER 2008 X64版本报错:消息 7302,级别 16,无法创建链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.ACE.OLEDB.12.0" 的实例。
    Response.Redirect(),Server.Transfer(),Server.Execute()的区别[转]
    ASP.net应用程序中如何调用客户端的Javascript脚本小结(转)
    重写ListView控件,实现点击列头排序的功能
    关于Response.redirect和Response.End出现线程中止异常的处理(转)
    持续集成cruisecontrol.net学习总结
    [转]关于PowerDesigner反向工程SQL Server2000数据库时生成注释的解决方法
    敏捷开发scrum学习笔记一
    asp.net缓存机制总结(转)
  • 原文地址:https://www.cnblogs.com/asdfsag/p/13631438.html
Copyright © 2011-2022 走看看