• 简单博弈论


    Nim游戏

    如果 (a_1) ^ (a_2) ^ (a_3) ^ (ldots) ^ (a_n) = 0,则先手必败,否则必胜。

    题意:n 堆石子,两位玩家可以从任意一堆中拿任意数量的石子,但是不能不拿,问先手是否必胜。

    #include <bits/stdc++.h>
    using namespace std;
    
    const char nl = '
    ';
    //const int N =
    
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int n;
        cin >> n;
    
        int res = 0;
        for (int i = 0, x; i < n; ++i){
            cin >> x;
            res ^= x;
        }
        if (res) cout << "YES" << nl;
        else cout << "NO" << nl;
    
        return 0;
    }
    
    

    SG 函数

    (sg(x_1)) ^ (sg(x_2)) ^ (sg(x_3)) ^ (ldots) ^ (sg(x_n)) = 0,则先手必败,否则必胜。

    题意:给定 n 堆石子以及 m 个不同正整数构成的集合 S,两位玩家只能从任意一堆中拿指定数量的石子,该数量必须包含于 S 集合中,问先手是否必胜。

    #include <bits/stdc++.h>
    using namespace std;
    
    const char nl = '
    ';
    const int N = 1e5 + 50;
    
    int n, m;
    int s[N], f[N];
    
    int sg(int x){
        if (f[x] != -1) return f[x];
    
        unordered_set<int> S;
        for (int i = 0; i < m; ++i){
            if (x >= s[i]) S.insert(sg(x - s[i]));
        }
        for (int i = 0; ; ++i)
            if (!S.count(i)) return f[x] = i;
    }
    
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        cin >> m;
        for (int i = 0; i < m; ++i) cin >> s[i];
    
        cin >> n;
        memset(f, -1, sizeof(f));
    
        int res = 0;
        for (int i = 0, x; i < n; ++i){
            cin >> x;
            res ^= sg(x);
        }
        if (res) cout << "YES" << nl;
        else cout << "NO" << nl;
    
        return 0;
    }
    
    
  • 相关阅读:
    java
    MVC4重复提交数据
    cache
    Nosql
    MVC4重复提交
    PHP Java
    .net performance
    How the Runtime Locates Assemblies
    android
    window.onscroll
  • 原文地址:https://www.cnblogs.com/xiaoran991/p/14410384.html
Copyright © 2020-2023  润新知