题目链接:AcWing 6118. 蛋糕游戏
知识点:主要是跟贪心,博弈论相关,还用了前缀和这一算法
题意:有n(偶数)个蛋糕排成一排,AB俩人对弈,规则为:
1.A只能合并相邻的蛋糕
2.B每次只能从两端拿一块蛋糕藏起来(其实就是直接吃掉)
3.A先开始操作,当场上只剩下一个蛋糕时候,A可以直接吃掉
读完题,我们的问题就是,AB应该怎么吃
A到底怎么合并,应该大概率要从中间开始,那从中间开始的话,我们应该往左还是往右
B呢?先吃右边还是左边,是看哪个大就先吃哪个吗?那会不会出现,A先在左边合并几个诈骗我的行为呢?总之一系列问题就是出现我们的脑海中,其实这些都是我们自己同时思考了很多种情况,所以显得问题很复杂,与其干想,不如我们将问题转化一下?
1.首先整体上看,A先合并,而n是偶数,因此可以得到A合并完,剩下的蛋糕总数变成了奇数,
然后B吃,B吃完又变成偶数,所以不难推出,最后剩下2个的时候,该A合并了,而A合并完,剩下一个,就可以直接吃掉,而A又是先手,所以在理想状态下(假定A合并的全都没被b吃掉),A吃的个数比B多2个,我们记为A-B=2,所以在理想状态下,A吃的个数为n/2+1,B的为n/2-1
2.其次,我们先对B考虑,B是吃俩边的,那么对于B来说,它至少可以吃n/2-1个,多吃是因为,A合并的被它吃掉,但B至少吃为n/2-1个,并且B在吃的时候,很自由,它想吃左边右边是无拘无束的,所以B至少可以吃个数为(n/2-1)个的总和最大的数,不论左边的还是右边的,假设蛋糕总和为T,没被吃掉的(中间的)n/2+1个总和为S,所以我们让S最小,那么B>=T-S(min),注意这个情况可能不是最优的,我们只是在考虑这一种特殊的情况,并且得出结论B>=T-S(min)
3.最后对于A呢,它是进行合并操作的,我们应该如何让它的策略最优呢?A最多能合并n/2+1个,优先合并中间的两个数,然后B左边吃了,我们就向右边合,就是走相反的路线,这样至少能保证A可以合并且吃下n/2+1个蛋糕,当然这也不一定是最优的情况,我们只是先这样考虑,接着上面的,A吃的n/2+1个蛋糕,那对于A来说这个情况最坏的是什么?是不是A吃的所有蛋糕全都是最小的,就是A起码能掉n/2+1个最小的蛋糕,所以A>=S(min)
4.A+B=T,A>=S(min),可推出B<=T-S(min),结合前面就得到B=T-S(min)
到此就找到了答案了,代码部分比较简单就不说啦,感谢你看我写的博客,祝你工作学习顺利,陌生人!
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=5e5+5;
int t,n;
ll S;
ll a[N],s[N];
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
{
S=LONG_LONG_MAX;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
}
for(int i=0;i<=n/2-1;i++)
{
S=min(S,s[i+n/2+1]-s[i]);
}
cout<<S<<" "<<s[n]-S<<endl;
}
return 0;
}