zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    URAL 2067 Friends and Berries (推理,数学)
    URAL 2070 Interesting Numbers (找规律)
    URAL 2073 Log Files (模拟)
    URAL 2069 Hard Rock (最短路)
    URAL 2068 Game of Nuts (博弈)
    URAL 2066 Simple Expression (水题,暴力)
    URAL 2065 Different Sums (找规律)
    UVa 1640 The Counting Problem (数学,区间计数)
    UVa 1630 Folding (区间DP)
    UVa 1629 Cake slicing (记忆化搜索)
  • 原文地址:https://www.cnblogs.com/mzl0707/p/6309030.html
Copyright © 2011-2022 走看看