D. Stoned Game 博弈论

传送门

题意

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;
}



猜你喜欢

转载自blog.csdn.net/tlyzxc/article/details/108369542