• bzoj1874: [BeiJing2009 WinterCamp]取石子游戏(博弈论+SG函数入门)


    昨天在唐神的引导下看了有关博弈论的知识,总算是有点了解,觉得这东西比较抽象,但是很神奇很有趣。

    一个nim游戏中,每堆石子的sg函数其实可以理解为此状态到不了的状态,我觉得从某种意义上来讲就可以代表此状态

    判断一个游戏局面先手是否必胜,求所有点的sg值得亦或和sum

    sum为0必败,其他必胜。原理可以百度“博弈论 sg函数”有详解

    同时如果有若干个子游戏,则sum为若干个子游戏的亦或和

    虽然看是看懂了,但是实际运用起来并不怎么通透。。

    此题为入门题,预处理出sg值

    sg值可以由所能到达的各状态的sg值推得

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn = 15; 
     6 int n,a[maxn],ans,sg[1001],f[maxn],m,hash[1001];
     7 
     8 void get_sg(){
     9     sg[0]=0;
    10     for (int i=1; i<=1000; i++){
    11         for (int j=1; j<=m && i-f[j]>=0; j++)
    12             hash[sg[i-f[j]]]=i;
    13         for (int j=0; j<=i+1; j++)
    14             if (hash[j]!=i){sg[i]=j;break;}
    15     }
    16 }
    17 
    18 int main(){
    19     scanf("%d", &n);
    20     for (int i=1; i<=n; i++) scanf("%d", &a[i]); 
    21     scanf("%d", &m);
    22     for (int i=1; i<=m; i++) scanf("%d", &f[i]);
    23     get_sg();
    24     for (int i=1; i<=n; i++) ans^=sg[a[i]];
    25     if (!ans){puts("NO");return 0;}
    26     for (int i=1; i<=n; i++){
    27         int tmp=ans^sg[a[i]];
    28         for (int j=1; j<=m && a[i]>=f[j]; j++)
    29             if (!(tmp^sg[a[i]-f[j]])){
    30                 puts("YES");
    31                 printf("%d %d
    ", i, f[j]);
    32                 return 0;
    33             }
    34     }
    35     return 0; 
    36 }
  • 相关阅读:
    加分二叉树
    逃离牧场
    [Apio2012]dispatching
    靶形数独
    POJ 1459-Power Network(网络流-最大流-ISAP)C++
    题解 最优的挤奶方案(Optimal Milking)
    [HNOI2007]紧急疏散EVACUATE (湖南2007年省选)
    【LCA求最近公共祖先+vector构图】Distance Queries
    BZOJ1143: [CTSC2008]祭祀river
    BZOJ2140: 稳定婚姻
  • 原文地址:https://www.cnblogs.com/mzl0707/p/6309030.html
Copyright © 2020-2023  润新知