hdu 4701 Game(博弈)

这篇博客介绍了HDU 4701博弈问题的详细解析,包括游戏规则、思路探讨以及解决方案。通过阅读,读者可以理解如何解决这类博弈问题,并学习到相关算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:hdu 4701 Game

代码

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;

/* 
 * S(i) 表示第i件物品到第N件物品的价值和
 * win(i, x, y) 表示当前可以买的物品为i,先手剩x元,后手剩y元时,先手是否必胜
 * x + y = A + B - S(1) + S(i);
 * 所以win(i, x, y) 可以化简为win(i, x)
 * 并且win(i, x) ==> win(i, x+1)
 *
 * 记m(i)为min{x: win(i, x)},则有!win(i, x) <==> x < min(i)
 * D = A + B - S(1) + S(i)
 *
 * m(i) = min{x:x >= S(i) - S(j) && j > i && !win(j, D-x)}
 *      = min{x:x >= S(i) - S(j) && j > i && D - x <= m(j) - 1}
 *      = min{x: max(S(i)-S(j), A + B - S(1) + S(i) - m(j) + 1) && j > i}
 *      = S(i) + min{ max(-S(j), A + B - S(1) - m(j) + 1) | j > i}
 *
 *  最后只要判断A是否大于m(1)即可
 */

int N, A, B;
ll S[maxn];

int main () {
    while (scanf("%d%d%d", &N, &A, &B) == 3) {
        for (int i = 0; i < N; i++) scanf("%lld", &S[i]);
        ll pre = S[N] = 0, now;
        for (int i = N-1; i >= 0; i--) S[i] += S[i+1];
        for (int i = N-1; i >= 0; i--) {
            now = pre + S[i];
            pre = min(pre, max(-S[i], (ll)A + B - S[0] + 1 - now));
        }
        printf("%s\n", A >= now ? "ALICE" : "BOB");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值