原文链接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. Net core 2.x 升级 3.0 使用自带 System.Text.Json 时区 踩坑经历

    .Net Core 3.0 更新的东西很多,这里就不多做解释了,官方和博园大佬写得很详细 关于 Net Core 时区问题,在 2.1 版本的时候,因为用的是 Newtonsoft.Json,配置比较 ...

  2. win10 idea启动Tomcat后控制台中文乱码

    idea 配置文件新增如下配置 -Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8

  3. Unity - Profiler参数详解

    CPU Usage ​       ● GC Alloc - 记录了游戏运行时代码产生的堆内存分配.这会导致ManagedHeap增大,加速GC的到来.我们要尽可能避免不必要的堆内存分配,同时注意:1 ...

  4. 论PM与团队与敏捷开发

    敏捷开发是每个有追求的PM都会去读的书 敏捷开发是很少程序会去读的书 敏捷开发是团体其他人很少会读的书 然而, 据我的 所见, 所闻, 所论 敏捷开发在大家的脑袋里分为很多种版本 既有可以一辩的新鲜思 ...

  5. centos安装docker以及docker-compose

    1.yum更新 # sudo yum update 2.如果安装docker旧版本,旧版本的卸载 # sudo yum remove docker docker-common docker-selin ...

  6. CSS标签选择器&类选择器

    基本选择器包括标签选择器.类选择器和ID选择器三类,其他选择器都是在这三类选择器的基础上组合形成 ##标签选择器 示例: <style type="text/css"> ...

  7. jQuery.each的function中有哪些参数

    1.没有参数 $("img").each(function(){ $(this).toggleClass("example"); }); 2.有一个参数,这个参 ...

  8. springboot启动后执行一段代码的方式

    文章转载自: https://www.cnblogs.com/zuidongfeng/p/9926471.html https://blog.csdn.net/zknxx/article/detail ...

  9. vue项目配置Mock.js

    扯在前面 最近一直在忙跳槽的事情,博客也好久没有更新了,上次更新还是去年,不出意外的话,从今天起继续今年的博客之旅. 今天继续完善我之前的项目架构,从零开始搭建vue移动端项目到上线,有需要的同学可以 ...

  10. vue $refs操作DOM

    原文链接:https://www.cnblogs.com/xumqfaith/p/7743387.html 如图,ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象 ...