2.26 贪心+前缀和

题目6118. 蛋糕游戏

题目分析

贝和埃分蛋糕,n个蛋糕,大小不一从a1到aN,两者轮流进行以下操作:

  • 贝的操作: 她每次选择两个相邻的蛋糕,将它们堆叠成一个新的蛋糕,蛋糕的大小等于这两个蛋糕的和
  • 埃的操作: 她每次选择最左边或最右边的一个蛋糕,将其藏起来

游戏结束时,剩下的唯一一个蛋糕由贝吃掉,而埃则吃掉她藏起来的所有蛋糕

贝和埃都会采用最优策略来尽量让自己得到更多的蛋糕。我们的目标是,给定 N 个蛋糕的大小,计算在两者最优策略下,贝和埃分别会吃到多少蛋糕

思路

贝为了防止他搓出的大蛋糕被埃抢,他的一切行为都是被动的,所以两人策略为:

  • :第一次必须拿中间两个蛋糕,之后必须根据埃的选择,向反方向合并蛋糕,才能保证不会被埃拿走

  • :从两边向中间拿蛋糕,使自己的蛋糕尽可能大

我们可以发现,埃可以找到一种最优方案,思路为:遍历埃的所有可能方案,找到最优方案,再求贝的

代码关键:
求埃拿走的蛋糕数(cnt)
因为贝先行动,举几个例子可以发现,在N为偶数时贝拿走的蛋糕比埃多2个,可列式:cnt + cnt + 2 = n,解得cnt = (n - 2) / 2
用前缀和,埃和贝的蛋糕总和都可用前缀和快速求出

代码实现

以下是用 C++ 实现的代码,它模拟了这个游戏的博弈过程,并计算出每个测试用例中贝和埃各自能吃到的蛋糕量。

#include<iostream>
#include<vector>
using namespace std;
using ll=long long;
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--){
        ll n,cnt;cin>>n;
        vector<ll> a(n+1),sum(n+1);
        for(int i=1;i<=n;i++){ 
            cin>>a[i];
            sum[i]=sum[i-1]+a[i];//前缀和
        }
        cnt=(n-2)/2;//埃的蛋糕数
        ll ai=0,be=0;//埃和贝得到的蛋糕
        //埃有主动权,枚举埃的可能,取最优
        ll i=1,j=n;//贝的范围,被动决定
        for(int k=0;k<=cnt;k++){
            ll al=sum[k]+(sum[n]-sum[n-cnt+k]);//埃的和
            if(al>ai){
                ai=al;//更新埃的和
                i=k+1,j=n-cnt+k;//更新贝的范围
            }
        }
        be=sum[j]-sum[i-1];//最后,根据范围计算贝的和
        cout<<be<<' '<<ai<<'\n';
    }
    return 0;
}
posted @   fufuaifufu  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示