题目描述

A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参加比赛。

与经典的取石子游戏相比,A公司举办的这次比赛的取石子游戏规则复杂了很多:

l 总共有N堆石子依次排成一行,第i堆石子有 ai个石子。

l 开始若干堆石子已被 A公司故意拿走。

l 然后两个玩家轮流来取石子,每次每个玩家可以取走一堆中的所有石子,但有一个限制条件:一个玩家若要取走一堆石子,则与这堆石子相邻的某堆石子已被取走(之前被某个玩家取走或开始被A公司故意拿走)。注意:第 1堆石子只与第 2堆石子相邻,第N堆石子只与第N-1堆石子相邻,其余的第 i堆石子与第i-1堆和第 i+1 堆石子相邻。

l 所有石子都被取走时,游戏结束。谁最后取得的总石子数最多,谁就获得了这场游戏的胜利。

作为这次比赛的参赛者之一,绝顶聪明的你,想知道对于任何一场比赛,如果先手者和后手者都使用最优的策略,最后先手者和后手者分别能够取得的总石子数分别是多少。

输入输出格式

输入格式:

第一行是一个正整数N,表示有多少堆石子。输入文件第二行是用空格隔开的N个非负整数a1, a2, ...,
aN,其中ai表示第i堆石子有多少个石子,ai =
0表示第i堆石子开始被A公司故意拿走。输入的数据保证0<=ai<=100,000,000,并且至少有一个i使得ai =
0。30%的数据满足2<=N<=100,100%的数据满足2<=N<=1,000,000。

输出格式:

仅包含一行,为两个整数,分别表示都使用最优策略时,最后先手者和后手者各自能够取得的总石子数,并且两个整数间用一个空格隔开。

输入输出样例

输入样例#1:
复制
输出样例#1: 复制
者取得9 + 1 + 7 = 17个石子,后手者取得2 + 4 + 3 = 9个石子。本题和一般的博弈问题不一样。本题不讨论输赢,只让选手得到尽量多的石子。
由于双方最终石子数之和是确定的,双方的目标就是使自己-别人的石子数差最大
化。
首先我们可以抽象问题:
有两个栈,若干个双头队列,总长度不超过$10^{6}$
每次可以从栈顶取一个数,也可以从双头队列选一端取一个数。
$2$人轮流以最大化自己数字和的目标取数,问最终结果。
如果只有一个栈,那么取法是一定的。
如果只有一个队列,如果是奇数个,取法也是一定的。如果是偶数个,先手会取
max(奇数位的和,偶数位的和).
本题的关键难点是组合策略。
如果可取元素都是递减的,比如
1 2 3 0 2 1 2 0 4 1
容易发现先手只要贪心地从能取的元素里面拣最大的取走即可。
这样不会给后手好情况。
由于每次一定可以取全场最大值,所以只要一次排序然后交替取值即可。
4 3 2 2 2 1 1 1
如果不是这样,我们可以通过 2 个操作来化简数列:
1. 如果最左端是 A B.. 或者最右端是..B A, 且 A>=B
那么双方在有其它方案时都不会愿意先取走 B,故这种情况可以留到博弈的最后。
由于石子数是确定的,可以直接推出最后谁取到了 A,算出相应差值。
由于可以留到游戏的最后,此时删除这两堆并不影响两人之前的决策。
2. 如果有一段 ..A B C..
且满足 B>=A B>=C
那么我们直接把 ABC 替换成一个 A+C-B 即可。
我们可以这样想:选 A,B,C 的时候是因为没有更好的决策而被迫选的。事实上当
全场没有大于 A+C-B 的石子堆可以直接取时,才会考虑取 A,C 中的一个。那么不管第
一次取 A,B,C 中的元素是从哪边,后手一定也没有别的更好的选择,既然先手选 A/C
都已是被迫了,所以后手选 B 一定不会是差的。留下来的一个也一定是当前不差的选
择。故先手一定取走 A+C,后手取走 B。从对分数差的贡献来看,我们可以直接把 A,B,C
代替成 A+C-B
 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lol;
int n,top,pd[],l,r,cnt,tot;
lol st[],ans,sum,a[];
bool cmp(lol a,lol b)
{
return a>b;
}
int main()
{int i;
cin>>n;
for (i=;i<=n;i++)
{
scanf("%lld",&st[++top]);
sum+=st[top];
if (st[top]==) pd[top]=;
tot+=(bool)st[top];
while (top>&&(!pd[top])&&(!pd[top-])&&(!pd[top-])&&(st[top-]>=st[top])&&(st[top-]>=st[top-]))
{
st[top-]=st[top]+st[top-]-st[top-];
top-=;
}
}
for (l=;(!pd[l])&&(!pd[l+])&&(st[l]>=st[l+]);l+=)
ans+=tot&?st[l]-st[l+]:st[l+]-st[l];
for (r=top;(!pd[r])&&(!pd[r-])&&(st[r]>=st[r-]);r-=)
ans+=tot&?st[r]-st[r-]:st[r-]-st[r];
for (i=l;i<=r;i++)
if (pd[i]==) a[++cnt]=st[i];
sort(a+,a+cnt+,cmp);
for (i=;i<=cnt;i++)
{
if (i&) ans+=a[i];
else ans-=a[i];
}
cout<<(sum+ans)/<<' '<<(sum-ans)/<<endl;
}

[HNOI2010]STONE取石头游戏的更多相关文章

  1. bzoj2000 [Hnoi2010]stone 取石头游戏

    Description A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参加比赛. 与经典的取石子游戏相 ...

  2. BZOJ.2000.[HNOI2010]stone取石头游戏(博弈)

    BZOJ 洛谷 低估这道神题了_(:з」∠)_ MilkyWay好狠啊(小声) \(Description\) 有一些数字,被分成若干双端队列(从两边都可以取)和最多两个栈(只能从某一边一个一个取)的 ...

  3. [luogu] P3210 [HNOI2010]取石头游戏(贪心)

    P3210 [HNOI2010]取石头游戏 题目描述 A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参 ...

  4. 【BZOJ2000】[HNOI2000]取石头游戏(贪心,博弈论)

    [BZOJ2000][HNOI2000]取石头游戏(贪心,博弈论) 题面 BZOJ 洛谷 题解 这题好神仙啊,窝不会QaQ. 假装一下只有三个元素\(a_{i-1},a_i,a_{i+1}\),并且满 ...

  5. luogu P3210 [HNOI2010]取石头游戏

    传送门 不会结论做个鬼系列 题意其实是在头尾(最多)两个栈以及中间一些双端队列依次取数,然后每个人都要最大化自己的价值 有一个结论,如果一段序列中,出现了三个相邻位置\(A,B,C\),满足\(A\l ...

  6. 题解 洛谷 P3210 【[HNOI2010]取石头游戏】

    考虑到先手和后手都使用最优策略,所以可以像对抗搜索一样,设 \(val\) 为先手收益减去后手收益的值.那么先手想让 \(val\) 尽可能大,后手想让 \(val\) 尽可能小. 继续分析题目性质, ...

  7. HDU 1729 Stone Game 石头游戏 (Nim, sg函数)

    题意: 有n个盒子,每个盒子可以放一定量的石头,盒子中可能已经有了部分石头.假设石头无限,每次可以往任意一个盒子中放石头,可以加的数量不得超过该盒中已有石头数量的平方k^2,即至少放1个,至多放k^2 ...

  8. Games:取石子游戏(POJ 1067)

    取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37662   Accepted: 12594 Descripti ...

  9. CH 3401 - 石头游戏 - [矩阵快速幂加速递推]

    题目链接:传送门 描述石头游戏在一个 $n$ 行 $m$ 列 ($1 \le n,m \le 8$) 的网格上进行,每个格子对应一种操作序列,操作序列至多有 $10$ 种,分别用 $0 \sim 9$ ...

随机推荐

  1. RabbitMQ封装实战

    先说下背景:上周开始给项目添加曾经没有过的消息中间件.虽然说,一路到头非常容易,直接google,万事不愁~可是生活远不仅是眼前的"苟且".首先是想使用其他项目使用过的一套对mq封 ...

  2. Beta Scrum Day 1

    听说

  3. APP的案例分析-美团外卖

    大一才开始用软件订外卖了,很方便  ,上手快只要注册个账号登陆即可,支付时自动跳转到其他支付应用.严重的bug也没有,只有之前一段时间通过首单可以刷优惠,之后也修复了. 身边的同学也很多都在用.方便省 ...

  4. Alpha冲刺Day6

    Alpha冲刺Day6 一:站立式会议 今日安排: 由张梨贤继续完成前一天委托第三方剩余的内容,并完成委托情况查看这一子模块 由黄腾飞继续完成前一天企业自查风险管理剩余的内容,并完成风险上报这一子模块 ...

  5. 201621123057 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰 ...

  6. 彻底搞懂shell的高级I/O重定向

    本文目录: 1.1 文件描述符(file description,fd) 1.2 文件描述符的复制 1.3 重定向顺序很重要:">file 2>&1"和&quo ...

  7. LeetCode & Q167-Two Sum II - Input array is sorted-Easy

    Array Two Pointers Binary Search Description: Given an array of integers that is already sorted in a ...

  8. Python扩展模块——自动化(testlinkAPI的使用)

    使用TESTLINKAPI首先要安装TestLink_API_Python_client-0.6.4(当前最新版本) 目前只使用到了通过api获取testlink中的自定义字段and值 url = ' ...

  9. php 数组对象之间的转换

    在之前我写过php返回json数据简单实例 从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码. 一.json_encode() 1 ...

  10. svn介绍和安装

      什么是SVN呢,作用是什么: SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS/CVS,它采取了分支管理系统,它的设计目标就是取代CVS.SVN就是用于多个人共同开 ...