luogu P3210 [HNOI2010]取石头游戏
不会结论做个鬼系列
题意其实是在头尾(最多)两个栈以及中间一些双端队列依次取数,然后每个人都要最大化自己的价值
有一个结论,如果一段序列中,出现了三个相邻位置\(A,B,C\),满足\(A\le B\ge C\),那么可以把这三个数替换成\(A-B+C\).原因是假设先手某一次要取\(A\)(要取\(C\)同理),显然如果要取\(A\)说明此时\(A\)是最优决策废话,然后后手后面一定会取\(B\),因为先手的最优决策都是\(A\)而不是其他的,那么后手选\(B\)一定不差,不然先手为什么不选别的呢?同理,先手后面会取\(C\),如果不取\(C\)那他也不会白给后手一个\(B\)啊,所以这样取完三个数先手收益就是\(A-B+C\)
然后这样做完以后,所有栈/队列都会变成先递减然后递增的形式.对于队列,因为可以从两边取,那么每次只要取最大的就完事了,所以可以把所有队列元素放在一起排序,然后依次取;对于栈元素,从栈顶开始一直递减的那一段也是和队列一样的,但是递增的一段,显然先手一取,后手就会取下一个,导致先手亏,所以谁都不会先取,这一部分单独拎出来处理,即从栈底开始两两配对,把亏损的代价统计一下,然后放在最后面,看谁会取到
// luogu-judger-enable-o2
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db double
using namespace std;
const int N=1e6+10;
const LL inf=1ll<<50;
LL rd()
{
    LL x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int n,m,p[N][2];
LL a[N],sm,dd,st[N],tp,b[N],tb;
int main()
{
    n=rd();
    for(int i=1;i<=n;++i)
    {
        a[i]=rd();
        sm+=a[i];
        if(a[i])
        {
            if(!a[i-1]) p[++m][0]=i;
            p[m][1]=i;
        }
    }
    for(int i=1;i<=m;++i)
    {
        tp=0;
        for(int j=p[i][0];j<=p[i][1];++j)
        {
            st[++tp]=a[j];
            while(tp>=3&&st[tp-1]>=st[tp]&&st[tp-1]>=st[tp-2])
            {
                LL nw=st[tp]-st[tp-1]+st[tp-2];
                --tp,--tp,--tp;
                st[++tp]=nw;
            }
        }
        if(i==1&&a[1])
        {
            int j=1;
            for(;j+1<=tp&&st[j]>=st[j+1];) b[0]+=st[j+1]-st[j],++j,++j;
            while(tp>=j) b[++tb]=st[tp--];
        }
        else if(i==m&&a[n])
        {
            for(int j=1;j<=tp/2;++j) swap(st[j],st[tp-j+1]);
            int j=1;
            for(;j+1<=tp&&st[j]>=st[j+1];) b[0]+=st[j+1]-st[j],++j,++j;
            while(tp>=j) b[++tb]=st[tp--];
        }
        else
        {
            while(tp) b[++tb]=st[tp--];
        }
    }
    sort(b+1,b+tb+1);
    int ii=1;
    while(~tb)
    {
        LL dt=b[tb--];
        if(ii) dd+=dt;
        else dd-=dt;
        ii^=1;
    }
    printf("%lld %lld\n",(sm+dd)>>1,(sm-dd)>>1);
    return 0;
}
luogu P3210 [HNOI2010]取石头游戏的更多相关文章
- [luogu] P3210 [HNOI2010]取石头游戏(贪心)
		P3210 [HNOI2010]取石头游戏 题目描述 A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参 ... 
- 题解 洛谷 P3210 【[HNOI2010]取石头游戏】
		考虑到先手和后手都使用最优策略,所以可以像对抗搜索一样,设 \(val\) 为先手收益减去后手收益的值.那么先手想让 \(val\) 尽可能大,后手想让 \(val\) 尽可能小. 继续分析题目性质, ... 
- 【BZOJ2000】[HNOI2000]取石头游戏(贪心,博弈论)
		[BZOJ2000][HNOI2000]取石头游戏(贪心,博弈论) 题面 BZOJ 洛谷 题解 这题好神仙啊,窝不会QaQ. 假装一下只有三个元素\(a_{i-1},a_i,a_{i+1}\),并且满 ... 
- [HNOI2010]STONE取石头游戏
		题目描述 A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参加比赛. 与经典的取石子游戏相比,A公司举办 ... 
- bzoj2000 [Hnoi2010]stone 取石头游戏
		Description A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参加比赛. 与经典的取石子游戏相 ... 
- BZOJ.2000.[HNOI2010]stone取石头游戏(博弈)
		BZOJ 洛谷 低估这道神题了_(:з」∠)_ MilkyWay好狠啊(小声) \(Description\) 有一些数字,被分成若干双端队列(从两边都可以取)和最多两个栈(只能从某一边一个一个取)的 ... 
- 【Luogu】P2599取石子游戏(博弈论)
		题目链接 情况非常复杂,事实上题解我现在也没有完全理解 不过大致的意思就是 设两个数组lef[][],rig[][]表示对应区间左端加一堆数量为lef[][]的石子使得先手必败,rig同理 可以通过一 ... 
- luogu 4411 [BJWC2010]取数游戏 约数+dp
		不大难的dp,暴力拆一下约数然后按照约数来统计即可. 注意:vector 很慢,所以一定特判一下,如果没有该数,就不要添加. Code: #include <bits/stdc++.h> ... 
- [LuoguP1005]矩阵取数游戏 (DP+高精度)
		题面 传送门:https://www.luogu.org/problemnew/show/P1005 Solution 我们可以先考虑贪心 我们每一次都选左右两边尽可能小的数,方便大的放在后面 听起来 ... 
随机推荐
- R_Studio(学生成绩)使用主成分分析实现属性规约
			对11_1_4.csv成绩表进行主成分分析处理 setwd('D:\\data') list.files() #读取数据 dat=read.csv(file="11_1_4.csv" ... 
- JS框架_(Popup.js)3D对话框窗口插件
			百度云盘 传送门 密码:afdo 3D对话框窗口插件效果: <!doctype html> <html lang="zh"> <head> &l ... 
- Error:Connection activation failed: No suitable device found for this connection
			原文链接: https://blog.csdn.net/baiboya/article/details/80452822 ens33这个网卡一直无法激活,在网上找了半天,找到这个博主的文章,才解决,虽 ... 
- watir安装——windows环境
			默认情况下,gem sources 都是https://rubygems.org/ 
- nodejs 中的 cookie 及 session
			cookie-parser 插件:cookie解析,加密的操作 cookie-session 插件:session 的解析操作 http 是无状态的 cookie:在浏览器保存一些数据,每次向服务器发 ... 
- CPU处理多任务——中断与轮询方式比较
			中断方式与轮询方式比较 中断的基本概念 程序中断通常简称中断,是指CPU在正常运行程序的过程中,由于预选安排或发生了各种随机的内部或外部事件,使CPU中断正在运行的程序,而转到为相应的服务程序去处 ... 
- 子系统 安装vsftpd
			1.安装命令 sudo apt install vsftpd 2.为FTP添加用户,使用sudo useradd -m sunftp命令添加一个sunftp的用户 3. 授权文件夹 chmod 77 ... 
- Kubernetes 中文文档
			Kubernetes 中文文档 如果想学习 Kubernetes 的小伙伴,可以参考如下文档学习: https://www.kubernetes.org.cn/docs 文档中详细讲解了 k8s 的设 ... 
- cento7忘记root密码怎么办
			1.首先开启系统,一直按 e 键 进入编辑选项 2.光标下移,在UTF-8行这一段修改两处,首相找到ro改为rw,即只读改为可读写权限:然后在这段的尾部加入 init=/bin/sh 3.此时按住Ct ... 
- 依赖注入——angular
			在Angular中创建一个对象时,需要依赖另一个对象,这是代码层的一种依赖关系,当这种依赖被声明后,Angular通过injector注入器将所依赖的对象进行注入操作. 一.依赖注入的原理 看下面的示 ... 
