zoukankan      html  css  js  c++  java
  • [九省联考 2018]一双木棋chess

    Description

    题库链接

    给出一个 (n imes m) 的棋盘,棋盘的每个格子有两个权值 (A,B) 。 Alice 和 Bob 轮流操作在棋盘上放棋子,一个格子能放棋子的前提条件是这个格子的左侧和上侧均放了棋子。对于 Alice 放棋子的格子,能获得该格子的 (A) 的权值;对于 Bob 放棋子的格子,能获得该格子的 (B) 的权值。 Alice 想最大化得分差, Bob 想最小化得分差,求最后得分差。

    (1leq n,mleq 10)

    Solution

    比较简单啊,状压轮廓线记搜就好了。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 10+5;
    const int SIZE = (1<<20)+5;
    
    int n, m, a[N][N], b[N][N], bin[N<<1];
    int f[SIZE], inf;
    
    int dfs(int S, int who) {
        if (f[S] != -inf) return f[S];
        int ans = who ? -inf : inf;
        for (int i = 0, loc = 0; i < n+m; i++) {
            if (S&bin[i]) ++loc;
            if (S&bin[i+1] && !(S&bin[i])) {
                int t = dfs(S-bin[i+1]+bin[i], who^1);
                if (who == 1) ans = max(ans, t+a[n-i+loc][loc+1]);
                else ans = min(ans, t-b[n-i+loc][loc+1]);
            }
        }
        if (abs(ans) == inf) ans = 0; f[S] = ans;
        return f[S];
    }
    void work() {
        memset(f, 128, sizeof(f)); inf = -f[0];
        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]);
        bin[0] = 1; for (int i = 1; i <= 21; i++) bin[i] = (bin[i-1]<<1);
        int states = 0;
        for (int i = 1; i <= m; i++) states |= bin[n-1+i];
        printf("%d
    ", dfs(states, 1));
    }
    int main() {work(); return 0; }
  • 相关阅读:
    二进制安装postgresql
    php mongodb扩展安装
    coinbase交易冻结时间
    linux服务器及工具常用命令
    PM2下使用 执行npm命令
    phpstorm安装PHP_CodeSniffer
    TP5 save遍历更新,过滤相邻重复字段,问题汇总
    mysqlbinlog 数据恢复
    设计模式之状态机模式
    关于c++中sleep_for函数的总结分析
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8970881.html
Copyright © 2011-2022 走看看