agc026F Manju Game

30 篇文章 0 订阅
4 篇文章 0 订阅

agc026F Manju Game

  • 从左到右有 n n n个物品,每一个价值为 a i a_i ai

  • 现在A和B轮流取物品。

  • 不妨假设现在先手的人是A,他可以任意取一个,假设是 x x x,后手的人可以取任意一个与 x x x相邻的物品,如果取 x + 1 x+1 x+1,那么将轮流往右取直到没有,反之取 x − 1 x-1 x1将轮流往左取直到没有。

  • 取完一个物品之后重标号。

  • 一开始A先手,A、B都想让自己取的物品最大,求他们在最优策略下最后各获得多大的价值。

  • n ≤ 3 e 5 , a i ≤ 1 e 3 n\le3e5,a_i\le1e3 n3e5,ai1e3

Solution

  • 神奇的博弈题,需要深入思考先手和后手的策略,以及先后手的转换。
  • 先手要发挥主观能动性,后手要尽可能获得先手权,由于确定方向之后选择是固定的,我们可以从先手的选择讨论是否会交换先手权。
  • n n n为偶数:
    • 显然A可以直接选开头或结尾,取走奇数位置或偶数位置的物品。
    • 注意到如果A选择中间的某一个,一定有一边剩下偶数个,B可以借此机会获得先手权,因为B如果把先手权让出去,另一边与A的安排一样,之后又继续在A的掌控之下了,所以B获得先手权能让偶数个那边在A安排下,另一边不比原先劣(先手的优势)。
    • 那么但凡A选择中间的,B获得先手,就比A的安排下(只直接选择头或尾)不劣,A不想看到这种情况。
    • 得出结论,A一定选头或尾。
  • n n n为奇数:
    • A选择了奇数位:
      • 类似上面的情况,如果不选择头或尾,会交出先手权,使得选择位置有一边在A的安排下,另一边失去控制,B的选择会更优。
      • 因此A一定选择头或尾。
    • A选择了偶数位:
      • 不管B选择左边还是右边,先手权始终在A的手上。
      • 但是A选择中间的某个位置之后,B可以选择把接下来的局面往左侧或右侧引导,最终到某个时候剩下一个奇数区间,A发现很有利的时候直接走奇数位——选择头或尾。
      • 单独考虑A的选择,我们选若干个偶数位置,B只能决定左右,但是A能决定端点,假设B知道了A的决策——即选出的位置,肯定会往最终对B最有利的区间引导,所以A想让B引导到的最小值还是最大的。
      • 因此问题转化为了选择若干个偶数位置,使得每个相邻区间对A的好处的最小值最大(我们将好处定义为“A贡献”-“B贡献”)。
      • 直接二分,贪心判定即可。
  • 至此可以在 O ( n   l o g   w ) O(n\ log \ w) O(n log w)内解决。
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define maxn 300005
using namespace std;

int n,i,j,k,a[maxn],s[maxn];

int check(int mid){
	int mi=0;
	for(i=1;i<=n/2+1;i++) if (s[i]+a[i*2]-mi>=mid) 
		mi=min(mi,s[i]);
	else if (i==n/2+1) return 0;
	return 1;
}

int main(){
	freopen("ceshi.in","r",stdin);
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&a[i]);
	if (n&1){
		for(i=1;i<=n/2+1;i++) s[i]=s[i-1]+a[2*i-1]-a[2*i];
		int l=-1e9,r=1e9,mid,ans=-1e9;
		while (l<=r){
			mid=(l+r)>>1;
			if (check(mid)) ans=mid,l=mid+1;
			else r=mid-1;
		}
		int sum=-s[n/2+1]+ans*2,s0=0;
		for(i=1;i<=n;i++) s0+=a[i];
		printf("%d %d\n",(sum+s0)/2,(s0-sum)/2);
	} else {
		int s1=0,s2=0;
		for(i=1;i<=n;i+=2) s1+=a[i],s2+=a[i+1];
		if (s1<s2) swap(s1,s2);
		printf("%d %d\n",s1,s2);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值