• [LUOGU] P4363 [九省联考2018]一双木棋chess


    题目描述
    菲菲和牛牛在一块n 行m 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束。
    
    落子的规则是:一个格子可以落子当且仅当这个格子内没有棋子且这个格子的左侧及上方的所有格子内都有棋子。
    
    棋盘的每个格子上,都写有两个非负整数,从上到下第i 行中从左到右第j 列的格 子上的两个整数记作 A_{i,j}A 
    i,j
    ​     、 B_{i,j}B 
    i,j
    ​    。在游戏结束后,菲菲和牛牛会分别计算自己的得分:菲菲的得分是所有有黑棋的格子上的 A_{i,j}A 
    i,j
    ​     之和,牛牛的得分是所有有白棋的格子上的 B_{i,j}B 
    i,j
    ​     的和。
    
    菲菲和牛牛都希望,自己的得分减去对方的得分得到的结果最大。现在他们想知道,在给定的棋盘上,如果双方都采用最优策略且知道对方会采用最优策略,那么,最终的结果如何。
    
    输入输出格式
    输入格式:
    从文件chess.in 中读入数据。
    
    输入第一行包含两个正整数n;m,保证n;m <= 10。
    
    接下来n 行,每行m 个非负整数,按从上到下从左到右的顺序描述每个格子上的 第一个非负整数:其中第i 行中第j 个数表示 A_{i,j}A 
    i,j
    ​     。
    
    接下来n 行,每行m 个非负整数,按从上到下从左到右的顺序描述每个格子上的 第二个非负整数:其中第i 行中第j 个数表示 B_{i,j}B 
    i,j
    ​     。
    
    输出格式:
    输出到文件chess.out 中。
    
    输出一个整数,表示菲菲的得分减去牛牛的得分的结果。
    
    输入输出样例
    输入样例#12 3
    2 7 3
    9 1 2
    3 7 2
    2 3 1
    输出样例#12

    对抗搜索,dfs记录玩家不能用剩下的,因为n*m奇偶不确定,初始值要特判
    不如用bool存,wa良久
    感谢wxl学长 QwQ

    #include<iostream>
    #include<cstdio>
    #include<map>
    using namespace std;
    
    typedef long long ll;
    
    const ll MAXN=16;
    const ll INF=1<<30;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    
    ll pow(ll x,ll y){
        ll ret=1;
        while(y){
            if(y&1) ret*=x;
            x*=x;
            y>>=1;
        }
        return ret;
    }
    
    
    const int t=2;
    const int tt=2*MAXN;
    
    int n,m,base;
    map<ll,ll> f;
    
    //int a[MAXN][MAXN][2];
    int a[MAXN*MAXN*2];
    int take[MAXN];
    ll dfs(ll sta,bool player){
        if(take[m]==n) return 0;
    //    if(res==1) return f[sta]=a[n][m][(n*m)&1];
        if(f.count(sta)) return f[sta];
    //    bool p=res&1;
        ll ret=-INF;
        for(int i=1;i<=m;i++){
            if((take[i]<n)&&(i==1||(take[i]<take[i-1]))){
                take[i]++;
                ret=max(ret,a[take[i]*tt+i*t+player]-dfs((ll)sta+pow(n+m,i-1),player^1));
                take[i]--;
            }
        }
        return f[sta]=ret;
    }
    
    
    int main(){
        n=rd();m=rd();
        for(int k=0;k<=1;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    a[i*tt+j*t+k]=rd();
    //                a[i][j][t]=rd(); 
                }
            }
        }
        printf("%lld",dfs(0ll,0));
        return 0;
    } 
    

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247388.html

  • 相关阅读:
    1.8 接口中的静态方法
    1.7 默认方法
    1.6 变量作用域
    汉字转拼音
    1.5 构造器引用
    1.4 方法引用
    循环中冲不掉外部定义的变量
    getBoundingClientRect
    Angular1.0 在Directive中调用Controller的方法
    horizontalDragMaxWidth:0;就没有水平滚动条了
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247388.html
Copyright © 2020-2023  润新知