zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Jmeter(十三)用Jmeter自带录制工具代理录制手机端应用脚本APP脚本
    AppScan 扫描测试策略
    AppScan 工作原理
    AppScan扫描结果分析及工具栏使用
    Java学习之正则表达式
    Java学习之反射练习
    Java学习之反射
    Java学习之网络编程(TCP协议实例)
    Java学习之网络编程(UDP协议实例)
    Java学习之IO(编码练习--截取字符串根据字节)
  • 原文地址:https://www.cnblogs.com/kjd123456/p/14990212.html
Copyright © 2011-2022 走看看