CF 666 (Div. 2) D. Stoned Game博弈论
Posted lasomisolaso~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 666 (Div. 2) D. Stoned Game博弈论相关的知识,希望对你有一定的参考价值。
题意:
有 n n n堆石头,两个人轮流拿石头。每个人只能从一堆石头中拿走一个,并且这堆石头不能是上一轮另外一个玩家拿过的。谁没有石头拿就输了。
思路:
设当前所有石头堆的石头数量的总和为 S S S。
第一种情况:如果某一堆石头的个数大于 ⌊ S 2 ⌋ \\lfloor \\fracS2 \\rfloor ⌊2S⌋ ,那么肯定是先手获胜,就是面临这种情况的玩家必胜。
如果一堆石头大于 ⌊ S 2 ⌋ \\lfloor \\fracS2 \\rfloor ⌊2S⌋ ,那么其它所有石头的和都比这堆石头少。那么先手只要一直拿这堆石头,后手只能拿其它的石头。一定是后手先将其它的石头消耗完。
第二种情况:如果所有的堆的石头个数都小于等于 ⌊ S 2 ⌋ \\lfloor \\fracS2 \\rfloor ⌊2S⌋ ,并且石头的个数是偶数,那这种情况一定是后手胜。也就是说面临这种情况的玩家将必然输。
证明:先手从 n n n堆石头中取出1个石头,石头数量变成 S − 1 S-1 S−1 。 后手检查所有的石头,看是否有石头堆的石头个数大于 ⌊ S − 1 2 ⌋ \\lfloor \\fracS-12 \\rfloor ⌊2S−1⌋, 有的话直接转第一种情况 ,后手获胜;否则后手就可以随便的拿一个石头。这样石头总数变为 S − 2 S-2 S−2 , 还是所有的石头堆的石头数量都小于 ⌊ S − 2 2 ⌋ \\lfloor \\fracS-22 \\rfloor ⌊2S−2⌋ 。这是因为 ⌊ S − 1 2 ⌋ \\lfloor \\fracS-12 \\rfloor ⌊2S−1⌋ = ⌊ S − 2 2 ⌋ \\lfloor \\fracS-22 \\rfloor ⌊2S−2⌋ ,因为 S S S是偶数,后手没拿之前就已经没有大于 ⌊ S − 1 2 ⌋ \\lfloor \\fracS-12 \\rfloor ⌊2S−1⌋ 的,拿了之后更不可能。
还有,因为没有一堆石头的石头个数是大于 ⌊ S 2 ⌋ \\lfloor \\fracS2 \\rfloor ⌊2S⌋, 所以先手拿了之后后手必然是可以继续拿的。
所以这种情况就是,先手拿之后,后手不是转成必胜,就可以继续拿。所以后手必胜。
第三种情况:如果所有的堆的石头个数都小于等于 ⌊ S 2 ⌋ \\lfloor \\fracS2 \\rfloor ⌊2S⌋ ,并且石头的个数是奇数。这种情况先手必胜。
因为先手随便拿一个石头,石头总数变为 S − 1 S-1 S−1, S S S是奇数, ⌊ S 2 ⌋ \\lfloor \\fracS2 \\rfloor ⌊2S⌋ = ⌊ S − 1 2 ⌋ \\lfloor \\fracS-12 \\rfloor ⌊2S−1⌋ , 所以所有的石头堆的个数还是小于 ⌊ S 2 ⌋ \\lfloor \\fracS2 \\rfloor ⌊2S⌋ , S S S变为偶数,情况转为第二种情况,只是这个时候后手面临这种情况,那后手就必败。
代码:
/*
* @file D.cpp
* @path D:\\code\\ACM\\codeforces\\Div2_666\\D.cpp
* @author Xiuchen
* @date 2020-09-23 21:51:57
*/
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<cmath>
#include<math.h>
#include<iostream>
#include<algorithm>
//#define DEBUG
#define dbg(x) cout << #x << " = "<< (x) << endl
#define dbg2(x1,x2) cout << #x1 << " = " << x1 << " " << #x2 << " = " << x2 << endl
#define dbg3(x1,x2,x3) cout<< #x1 << " = " << x1 << " " << #x2 << " = " << x2 << " " << #x3 << " = " << x3 <<endl
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 110;
int gcd(int a, int b)
return b ? gcd(b, a % b) : a;
int t, n;
int a[maxn];
int main()
#ifdef DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
scanf("%d", &t);
while(t--)
scanf("%d", &n);
int sum = 0;
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), sum += a[i];
sort(a + 1, a + n + 1);
if(a[n] > sum / 2) printf("T\\n");
else
if(sum % 2 == 0) printf("HL\\n");
else printf("T\\n");
return 0;
以上是关于CF 666 (Div. 2) D. Stoned Game博弈论的主要内容,如果未能解决你的问题,请参考以下文章
CF #374 (Div. 2) D. 贪心,优先队列或set
CF-Div2-832 D. Yet Another Problem(bitmask&结论)
CF-Div2-832 D. Yet Another Problem(bitmask&结论)