原文链接www.cnblogs.com/zhouzhendong/AGC026F.html

前言

太久没有发博客了,前来水一发。

题解

不妨设先手是 A,后手是 B。定义 \(i\) 为奇数时,\(a_i\) 为"奇数位上的数";\(i\) 为偶数时, \(a_i\) 为"偶数位上的数"。定义左、右两端的数分别表示 \(a_1\) 和 \(a_n\)。

考虑第一步:

首先,如果 A 取了左右某一个端点,那么他必然能取走和他取的点奇偶性相同的所有点。

然后,我们考虑 A 取了一个中间点后会发生什么:如果这个点左边和右边的剩余点数都是奇数,那么无论 B 取左还是右,取完某一边之后,问题规模缩小成另一边的情况,A 一定还是先手;否则 B 就可以取剩余点数为偶数的那一边,并成为先手。

考虑 n 为偶数的情况。

如果 A 取了一个中间点,那么一定有一边剩余奇数个,一边剩余偶数个。那么 B 一定先操作偶数个的那一边,然后获得奇数那一边的先手权,然后取最优策略。那么 A 还不如直接取偶数那一边的端点,这样做不仅取到了前一种方案能取到的,而且让 B 在另一边没有了先手选择权,一定不劣于前一种方案。

所以,当 n 为偶数时,先手能取到的最大值为 max(奇数位之和, 偶数位之和) 。

n 为奇数的情况较为复杂。

但是同理,A 不会去取一个位于奇数位的数,这样会导致两边剩余个数都为偶数,不如直接取两端。

于是,n 为奇数时,A 只有两种策略:

  • 取端点,即拿走所有奇数位的数。
  • 取某一个偶数位的数。此时,如果 B 取左边,那么 A 会继续获得右边的先手权;否则 A 获得左边的先手权。这个过程可以看作问题规模的缩小。

如果将第二种策略用二叉树的形式表示出来,那么 B 一定会选择某一个叶子,使得最终答案最小。

考虑先假设所有偶数位的贡献都已被 A 收取,那么 A 在一个区间执行“取端点”操作得到的收益就是这个区间的奇数位之和减去偶数位之和(注意这里的两端点一定都是奇数)。

我们要做的是找出一个叶子集合,使得对这些叶子“取端点”的收益的最小值尽量大。

考虑二分答案x,之后问题转化为是否可以删除某些偶数位上的数,使得剩下的序列中任意一个极大的连续段之和都不小于x。

考虑暴力DP,枚举右端点,然后再暴力枚举前一个划分点。时间复杂度不可接受。

由于DP信息只有“能”和“不能”,所以我们可以考虑贪心,只保留“能”的点中前缀和最小的即可。

时间复杂度 \(O(n\log \sum a_i)\)。

代码

#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof x)
#define For(i,a,b) for (int i=(a);i<=(b);i++)
#define Fod(i,b,a) for (int i=(b);i>=(a);i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define outval(x) cerr<<#x" = "<<x<<endl
#define outtag(x) cerr<<"-----------------"#x"-----------------\n"
#define outarr(a,L,R) cerr<<#a"["<<L<<".."<<R<<"] = ";\
For(_x,L,R) cerr<<a[_x]<<" ";cerr<<endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=300005;
int n;
int a[N],s[N];
bool check(int x){
int v=0;
for (int i=1;i<n;i+=2)
if (s[i]-v>=x)
v=min(v,s[i+1]);
return s[n]-v>=x;
}
int main(){
n=read();
For(i,1,n)
a[i]=read();
if (n%2==0){
int s0=0,s1=0;
For(i,1,n)
if (i&1)
s0+=a[i];
else
s1+=a[i];
cout<<max(s0,s1)<<" "<<min(s0,s1)<<endl;
return 0;
}
For(i,1,n)
if (i&1)
s[i]=s[i-1]+a[i];
else
s[i]=s[i-1]-a[i];
int L=1,R=n*1000,mid,ans=L;
while (L<=R){
mid=(L+R)>>1;
if (check(mid))
L=mid+1,ans=mid;
else
R=mid-1;
}
For(i,1,n)
if (i%2==0)
ans+=a[i];
int s=0;
For(i,1,n)
s+=a[i];
cout<<ans<<" "<<s-ans<<endl;
return 0;
}

Atcoder Grand Contest 026 (AGC026) F - Manju Game 博弈,动态规划的更多相关文章

  1. AtCoder Grand Contest 026 (AGC026) E - Synchronized Subsequence 贪心 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/AGC026E.html 题目传送门 - AGC026E 题意 给定一个长度为 $2n$ 的字符串,包含 $n$ ...

  2. AtCoder Grand Contest 030 (AGC030) F - Permutation and Minimum 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/AGC030F.html 草率题解 对于每两个相邻位置,把他们拿出来. 如果这两个相邻位置都有确定的值,那么不管他. 然后把所有的 ...

  3. AtCoder Grand Contest #026 C - String Coloring

    Time Limit: 3 sec / Memory Limit: 1024 MB Score : 600600 points Problem Statement You are given a st ...

  4. AtCoder Grand Contest 002 (AGC002) F - Leftmost Ball 动态规划 排列组合

    原文链接https://www.cnblogs.com/zhouzhendong/p/AGC002F.html 题目传送门 - AGC002F 题意 给定 $n,k$ ,表示有 $n\times k$ ...

  5. AtCoder Grand Contest 026 D - Histogram Coloring

    一列中有两个连续的元素,那么下一列只能选择选择正好相反的填色方案(因为连续的地方填色方案已经确定,其他地方也就确定了) 我们现将高度进行离散化到Has数组中,然后定义dp数组 dp[i][j] 表示前 ...

  6. AtCoder Grand Contest #026 B - rng_10s

    Time Limit: 2 sec / Memory Limit: 1024 MB Score : 600600 points Problem Statement Ringo Mart, a conv ...

  7. AtCoder Grand Contest #026 A - Colorful Slimes 2

    Time Limit: 2 sec / Memory Limit: 1024 MB Score : 200200 points Problem Statement Takahashi lives in ...

  8. AtCoder Grand Contest 017D (AGC017D) Game on Tree 博弈

    原文链接https://www.cnblogs.com/zhouzhendong/p/AGC017D.html 题目传送门 - AGC017D 题意 给定一棵 n 个节点的以节点 1 为根的树. 两个 ...

  9. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

随机推荐

  1. 配置APP的图标

    https://www.cnblogs.com/hupo376787/p/10290840.html 上一篇文章说到  Flutter - 自动生成Android & iOS图标 通过flut ...

  2. Java电商项目,秒杀,抢购等高并发场景的具体场景和一些概念以及处理思路

    这里我借鉴了网上其他大佬的观点: 一:高并发带来的挑战 原因:秒杀抢购会经常会带来每秒几万的高并发场景,为了更快的返回结果给用户. 吞吐量指标QPS(每秒处理请求数),假设一个业务请求响应耗时为100 ...

  3. Jest did not exit one second after the test run has completed.

    使用 Jest 进行单元测试时出现如下问题: Jest did not exit one second after the test run has completed. This usually m ...

  4. iOS加密之AES

    心急的童鞋直接看这里Demo 运行之后可以去在线加密网站验证 AES(Advanced Encryption Standard)高级加密标准,又称Rijndael加密法,是美国联邦政府采用的一种区块加 ...

  5. SAP云平台上的SSO Principal Propagation设置

    我今天试图使用SAP云平台的SAP WebIDE Fullstack时,发现打不开, 遇到如下错误信息: You are not authorized to work with SAP Web IDE ...

  6. 1-Spark-1-性能调优-数据倾斜1-特征/常见原因/后果/常见调优方案

    数据倾斜特征:个别Task处理大部分数据 后果:1.OOM;2.速度变慢,甚至变得慢的不可接受 常见原因: 数据倾斜的定位: 1.WebUI(查看Task运行的数据量的大小). 2.Log,查看log ...

  7. 【hive】centos7下apache-hive-3.1.2-bin的安装测试

    前言:安装hive还是遇见些问题,但还好都解决了,比当初安装配置hadoop-3.2.0容易点...... 正文: 1.下载并安装hive:tar -zxvf apache-hive-3.1.2-bi ...

  8. MySQL Error--存储inode用完后报设备没有空间

    问题描述:磁盘有足够剩余空间,但在创建文件或文件夹时报错,提示“设备没有空间”. 问题原因:当存储设备通过分区格式化为文件系统后,会分为两部分:1.block部分: 存储的最小单位为扇区(Sector ...

  9. Oracle数据库 常用SQL

    -- 查询所有数据 SELECT * FROM [TABLE_NAME]; -- 查询数据总量 SELECT COUNT(*) AS COUNT FROM [TABLE_NAME]; -- 清空表内所 ...

  10. 实现Feign请求拦截器,对请求header等参数进行转发

    参考:Feign传递请求头信息(Finchley版本) 问题:通过Feign远程调用服务,无法传递header参数. 解决方式:实现RequestInterceptor接口(对所有的Feign请求进行 ...