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


    组合游戏

    当一个游戏满足如下几个性质:
    1.每个人都足够聪明
    2.游戏可以化归到有向无环图上
    3.游戏的内容是确定的
    则称这个游戏是组合游戏

    Solution

    该题中的游戏很明显是个组合游戏,另外题目中有条件“菲菲和牛牛都希望,自己的得分减去对方的得分得到的结果最大”,如果菲菲的贡献为正,牛牛的贡献为负,也就是说一个人希望总贡献最大,另一个人希望总贡献最小,对抗搜索就好了。

    Code:

    //直接用map存了状态,吸氧才过了
    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 20;
    
    int n,m;
    
    struct State{
        int num[MAXN];
        bool operator < (const State &x)const{
            for (int i = 1; i <= n; i++) {
                if (num[i] != x.num[i]) return num[i] < x.num[i];
            }
            return false;
        }
    };
    
    map<State,int> dp1,dp2;
    
    int a[MAXN][MAXN],b[MAXN][MAXN];
    
    int DFS2(State s);
    
    int DFS1(State s) {
        if (dp1.find(s) != dp1.end()) return dp1[s];
        int ret =  -1e9;
        for (int i = 1; i <= n; i++) {
            if (i == n && s.num[n] == m - 1 && s.num[n - 1] == m) return a[n][m];
            if (s.num[i] < m && (i == 1 || s.num[i] < s.num[i - 1])) {
                s.num[i]++;
                ret = max(ret,a[i][s.num[i]] + DFS2(s));
                s.num[i]--;
            }
        }
        return dp1[s] = ret;
    }
    
    int DFS2(State s) {
        if (dp2.find(s) != dp2.end()) return dp2[s];
        int ret = 1e9;
        for (int i = 1; i <= n; i++) {
            if (i == n && s.num[n] == m - 1 && s.num[n - 1] == m) return -b[n][m];
            if (s.num[i] < m && (i == 1 || s.num[i] < s.num[i - 1])) {
                s.num[i]++;
                ret = min(ret,-b[i][s.num[i]] + DFS1(s));
                s.num[i]--;
            }
        }
        return dp2[s] = ret;
    }
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                scanf("%d",&a[i][j]);
            }
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                scanf("%d",&b[i][j]);
            }
        }
        State begin;
        memset(begin.num,0,sizeof(begin.num));
        printf("%d
    ",DFS1(begin));
        return 0;
    }
    
  • 相关阅读:
    day 24
    day23
    day 22
    java中空格的操作
    java 解析Word文档以及Excel表格数据带有图片(2003/2007)
    java中创建文件夹
    http请求问题
    js弹框显示全部内容
    java实现HTTP请求的三种方式
    solr与java整合使用
  • 原文地址:https://www.cnblogs.com/kjd123456/p/14990212.html
Copyright © 2020-2023  润新知