D. Stoned Game 博弈论

tech2022-07-09  190

传送门

题意

T和HL两个人玩游戏,游戏规则为:由若干个非空堆,玩家选择一个非空堆,然后从中取出单个石头。但是,一个人不能选择在前一回合中选择的筹码(另一位玩家选择的筹码,或者如果当前回合是第一回合,则玩家可以选择任何非空筹码)。 不能依次选择一堆的玩家输了,游戏结束了。T先开始,两个人都很聪明,都会选择最优策略。 问T和HL谁能赢?

分析

首先我们得确定,在不违反规则的情况下,我们应该选择最大的那一堆石子

因为很明显,如果我选择了最大的一堆石子,那么不管我如何选择,下一轮我任然可以选择这堆石子,而对手选择次大堆的石子的话,下一轮这一堆石子依然是最大的,可以保证一直延续下去。 所以我们用一个优先队列进行维护即可

两种状态 1.T取出一堆石子,然后发现没有剩下的堆,T获胜 2.HL取出一堆石子,然后发现没有剩下的堆,HL获胜

我们可以很轻易的发现,如果HL取完石子,如果队列为空,那么一定HL获胜,因为如果剩下一堆石子,就会是HL取完剩下的那一堆,而这是次大堆,所以肯定还有另一堆石子存在,所以如果HL获胜那么一定就是HL取完之后队列为空才可

代码

#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <queue> #include <cstring> #define debug(x) cout<<#x<<":"<<x<<endl; #define _CRT_SECURE_NO_WARNINGS #pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline") #pragma GCC option("arch=native","tune=native","no-zero-upper") #pragma GCC target("avx2") using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PII; const int INF = 0x3f3f3f3f; const int N = 110; int a[N]; int n; int main(){ int T; scanf("%d",&T); while(T--){ priority_queue<int> Q; scanf("%d",&n); while(n--){ int x; scanf("%d",&x); Q.push(x); } while(Q.size()){ int x = Q.top(); Q.pop(); if(Q.empty()){ puts("T"); break; } int y = Q.top(); Q.pop(); if(x - 1) Q.push(x - 1); if(y - 1) Q.push(y - 1); if(Q.empty()){ puts("HL"); break; } } } return 0; }
最新回复(0)