Atcoder Grand Contest 026 (AGC026) F - Manju Game 博弈,动态规划
原文链接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 博弈,动态规划的更多相关文章
- AtCoder Grand Contest 026 (AGC026) E - Synchronized Subsequence 贪心 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/AGC026E.html 题目传送门 - AGC026E 题意 给定一个长度为 $2n$ 的字符串,包含 $n$ ...
- AtCoder Grand Contest 030 (AGC030) F - Permutation and Minimum 动态规划
原文链接www.cnblogs.com/zhouzhendong/p/AGC030F.html 草率题解 对于每两个相邻位置,把他们拿出来. 如果这两个相邻位置都有确定的值,那么不管他. 然后把所有的 ...
- 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 ...
- AtCoder Grand Contest 002 (AGC002) F - Leftmost Ball 动态规划 排列组合
原文链接https://www.cnblogs.com/zhouzhendong/p/AGC002F.html 题目传送门 - AGC002F 题意 给定 $n,k$ ,表示有 $n\times k$ ...
- AtCoder Grand Contest 026 D - Histogram Coloring
一列中有两个连续的元素,那么下一列只能选择选择正好相反的填色方案(因为连续的地方填色方案已经确定,其他地方也就确定了) 我们现将高度进行离散化到Has数组中,然后定义dp数组 dp[i][j] 表示前 ...
- AtCoder Grand Contest #026 B - rng_10s
Time Limit: 2 sec / Memory Limit: 1024 MB Score : 600600 points Problem Statement Ringo Mart, a conv ...
- AtCoder Grand Contest #026 A - Colorful Slimes 2
Time Limit: 2 sec / Memory Limit: 1024 MB Score : 200200 points Problem Statement Takahashi lives in ...
- AtCoder Grand Contest 017D (AGC017D) Game on Tree 博弈
原文链接https://www.cnblogs.com/zhouzhendong/p/AGC017D.html 题目传送门 - AGC017D 题意 给定一棵 n 个节点的以节点 1 为根的树. 两个 ...
- AtCoder Grand Contest 012
AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...
随机推荐
- C# 中关于重载与重写的区别及用法
1.重载(overload): 在同一个作用域(一般指一个类)的两个或多个方法函数名相同,参数列表不同的方法叫做重载,它们有三个特点(俗称两必须一可以): 方法名必须相同 参数列表必须不相同 返回值类 ...
- C# vb .net实现透视反射效果
在.net中,如何简单快捷地实现Photoshop滤镜组中的透视反射效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第 ...
- python day7: time,datetime,sys,pickle,json模块
目录 python day 7 1. time模块 2. datetime模块 2.1 date类 2.2 time类 2.3 datetime类 2.4 timedelta类 2.5 tzinfo时 ...
- UCOSIII系统内部任务
1. 空闲任务 空闲任务是UCOSIII创建的第一个任务 空闲任务是UCOSIII必须创建的 空闲任务优先级总是为OS_CFG_PRIO_MAK-1 空闲任务中不能调用任何可使空闲任务进入等待态的函数 ...
- 软件设计师【UML】
一.概述 二.核心概念 1.用例图 1.包含关系 当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示他们.其中这个提取出来的公共用例称为抽象用例,而把原始用例称为基本用例或基础用例. ...
- Nacos Docker集群部署
参考文档:https://nacos.io/zh-cn/docs/quick-start-docker.html 1.从git上下载nacos-docker项目,本地目录为/docksoft/naco ...
- ubuntu下关于profile和bashrc中环境变量的理解(转)
ubuntu下关于profile和bashrc中环境变量的理解(转) (0) 写在前面 有些名词可能需要解释一下.(也可以先不看这一节,在后面看到有疑惑再上来看相关解释) $PS1和交互式运行(r ...
- 【转】VC和VS的区别
各个版本之间的对应关系 使用windows平台搞开发时,下载第三方库时经常会遇到文件名以VCxx版本号命令,VC版本如何转换成对应的VS的版本呢,这里总结一下vc和vs的关系. Microsoft V ...
- System V共享内存
目录 1. 概述 2. System V共享内存API shmget shmat shmdt shmctl 3. 简单的程序 代码实现 common.h shmcreate.c shmrmid.c s ...
- mysqldump 备份与恢复数据库
备份数据库 mysqldump -u root -plvtao test > /home/bak.sql 数据库还原,常用source 命令登陆 mysql -u root -p mysql&g ...