【博弈论】BZOJ 1115-石子游戏

题意:有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数。两人轮流操作 每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件 谁没有石子可移时输掉游戏。问先手是否必胜。

这个题是一个阶梯博弈的问题。一开始没有接触过,各种度娘然后搞懂了,赶快记下来。

何为阶梯博弈?

简单的用Nim来说,一段台阶上,每个台阶上放了一堆石子,每次能从除了第一阶的台阶上取任意多石子向下放一级。无法操作的人输。

神犇告诉我,这个游戏的SG值就是奇数阶梯的SG值Xor起来...跪拜。

那么来证明一下。

如果只考虑奇数阶的情况我是必胜态,那么在这个游戏存在一个策略使我必胜——

  按只考虑奇数阶的策略行动。那么对手现在处于必败态。如果对手移动的是奇数阶的,依旧按照奇数阶的必胜策略行动。

  而如果对手移动的是偶数阶的,我可以将对手移动的石子再移动到下一阶。石子的数量和堆数都是之前我的状态,即对手的必败态。

  如此重复,偶数阶的最后一颗石子一定是我将某些数量的石子由2->1。

  可以看到,偶数阶对答案和决策并没有影响。

以上就是神奇的阶梯博弈!

那么这个题目需要稍微转换一下。

第i堆移走x个石子后,第i+1堆多了x个石子可以操作。是不是相当于将x个石子移动到了下一阶?

剩下的自己YY一下吧,贴个代码。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <iostream>
 5 using namespace std;
 6
 7 int ans,a[10005],n,i,T;
 8
 9 int main()
10 {
11     scanf("%d",&T);
12     while (T--)
13     {
14         scanf("%d\n",&n); ans = 0;
15         for (i = 1; i <= n; i++) scanf("%d",&a[i]);
16
17         for (i = n; i > 1; i -= 2) ans ^= (a[i]-a[i-1]);
18         if (n % 2) ans ^= a[1];
19
20         if (ans) printf("TAK\n"); else printf("NIE\n");
21     }
22
23     return 0;
24 }
25             

BZOJ 1115

时间: 2024-12-22 15:15:43

【博弈论】BZOJ 1115-石子游戏的相关文章

博弈论(取石子游戏)

参考题集就好了 http://url.cn/5qNJibq 基本博弈 1,巴什博奕(Bash Game):只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜. 必胜条件: n=(m+1)r+s 2,威佐夫博弈(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜. 必胜条件: 设两堆x,y(x<y) x != (int)[((sqrt(5)+1)/2)*(y-x) ]

bzoj 1115: [POI2009]石子游戏Kam -- 博弈论

1115: [POI2009]石子游戏Kam Time Limit: 10 Sec  Memory Limit: 162 MB Description 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必胜. Input 第一行u表示数据组数.对于每组数据,第一行N表示石子堆数,第二行N个数ai表示第i堆石子的个数(a1<=a2<=……<=an). 1

[BZOJ 1115] [POI2009] 石子游戏Kam 【阶梯博弈】

题目链接:BZOJ - 1115 题目分析 首先看一下阶梯博弈: 阶梯博弈是指:初始有 n 堆石子,每次可以从任意的第 i 堆拿若干石子放到第 i - 1 堆.最终不能操作的人失败. 解法:将奇数位的石子堆做最基本的 NIM 就可以了. WHY:对奇数位做 NIM 的必胜者总是可以胜利,因为如果从奇数位拿石子到偶数位,就相当于把这些石子拿走了,就是 NIM :如果必败者从偶数位将石子拿到奇数位,必胜者总是可以将这些石子再向前移一个位置,就又放到了偶数位,这样一直移动的话,最终会是必胜者将这些石子

BZOJ 1115: [POI2009]石子游戏Kam

1115: [POI2009]石子游戏Kam Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 924  Solved: 574[Submit][Status][Discuss] Description 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必胜. Input 第一行u表示数据组数.对于每组数据,第一行

【BZOJ 1115】 [POI2009]石子游戏Kam

1115: [POI2009]石子游戏Kam Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 551  Solved: 339 [Submit][Status] Description 有N堆石子,除了第一堆外,每堆石子个数都不少于前一堆的石子个数.两人轮流操作每次操作可以从一堆石子中移走任意多石子,但是要保证操作后仍然满足初始时的条件谁没有石子可移时输掉游戏.问先手是否必胜. Input 第一行u表示数据组数.对于每组数据,第一行N表示石子堆数

bzoj 1874 取石子游戏 题解 &amp; SG函数初探

[原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 334  Solved: 122 [Submit][Status] Description 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如果有,第一步如何取石子. In

BZOJ 1413 取石子游戏(DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1413 题意:n堆石子排成一排.每次只能在两侧的两堆中选择一堆拿.至少拿一个.谁不能操作谁输. 思路:参考这里. int f1[N][N],f2[N][N],n,a[N]; void deal() { RD(n); int i,j,k; FOR1(i,n) RD(a[i]),f1[i][i]=f2[i][i]=a[i]; int p,q,x; for(k=2;k<=n;k++) for(

【BZOJ 1874】 [BeiJing2009 WinterCamp]取石子游戏

1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 473  Solved: 186 [Submit][Status] Description 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如果有,第一步如何取石子. Input 输

bzoj 1874 取石子游戏 题解 &amp;amp; SG函数初探

[原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 334  Solved: 122 [Submit][Status] Description 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这种,每一个人每次能够从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,假设有,第一步怎样取石子. In