【BZOJ1413】[ZJOI2009]取石子游戏(博弈论,动态规划)

题面

BZOJ

洛谷

题解

神仙题.jpg。\(ZJOI\)是真的神仙。

发现\(SG\)函数等东西完全找不到规律,无奈只能翻题解。

首先设\(L[i][j]\)表示在\([i,j]\)这一段区间的左侧放上一堆数量为\(L[i][j]\)的石子后,先手必败。同理定义\(R[i][j]\)表示右侧。

首先我们可以证明\(L[i][j]\)唯一,假设存在两个\(L[i][j]\),显然较大的那个可以通过一步转移转移到较小的那个,所以不合法。因此\(L[i][j]\)唯一。

接下来考虑如何证明\(L[i][j]\)一定存在。假设\(L[i][j]\)不存在,那么对于这段区间而言,在左边加上任意一堆石子先手都必胜,既然先手必胜意味着先手进行一步操作之后可以到达一个必败态,这里分情况讨论。假设先手拿的是最左边的一堆石子,因为不存在\(L[i][j]\),所以只要拿了左边的石子之后,当前局面都是必胜态,所以不可能拿左边的石子。那么只能拿右边的石子,那么无论右边拿了一定量之后,无论左边添加了多少,都是一个必败态,那么此时后手在左侧随便拿走一定数量,这个状态也还是一个必败态,显然也不成立。因此\(L[i][j]\)必定存在。

综上,我们知道了\(L[i][j]\)一定存在并且唯一,而\(L[][],R[][]\)显然是对称的,因此\(R[i][j]\)也满足上述性质。

现在考虑如何求解\(L[i][j]\),\(R[i][j]\)同理。首先边界情况显然,\(L[i][i]=a[i]\),因为只剩下两堆一模一样的情况的时候,后手只需要模仿先手的行动对称执行就好了,这样子一定不会输,即先手必败。

接下来来大力分类讨论,为了方便(为了抄),设\(L=L[i][j-1],R=R[i][j-1],x=a[j]\)

  • \(x=R\)

    这种情况下显然只需要直接把\(a[j]\)放进去就好了,即这个区间本身就是一个必败态。所以\(L[i][j]=0\)。
  • \(x<L,x<R\)

    这种情况下\(L[i][j]=x\)。这种情况下最靠左的\(L[i][j]\)和\(x=a[j]\)是相同的,意味着先手无论怎么取,后手显然可以学着它的方法取,也就意味着左右两堆中显然必然会先拿完一堆,此时后手学着拿的那一堆的石子数一定也是小于\(L,R\)的。假设先手先拿完了最靠右的一堆,即剩下了\([i,j-1]\),因为\(L[i][j-1]\)表示的是在这一段区间最左侧加入一个\(L[i][j-1]\)的堆,无论先手怎么取先手都是必败的,那么我们等价的认为先手取走了这一堆的一部分,显然后手是必胜的。假如先手先取完的是最左的一堆,同理,\(R[i][j-1]\)的含义是在最右侧加入了一堆,而\(a[j]<R[i][j-1]\),我们还是可以等价的认为先手在这一堆中取走了若干石子,而这个状态对于先手而言是必败状态,因此显然后手必胜。
  • \(R<x<L\)

    这种情况下\(L[i][j]=x-1\)。这样子考虑,假设先手先拿了左边这一堆,那么假设还剩下了\(z\)个石子,如果\(z<R\),后手把右侧的那一堆也给拿成\(z\)就变成了上面的情况。如果\(z\ge R\),那么后手把最后那一堆拿成\(z+1\),于是又回到了这种情况,相当于这种情况递归处理。如果先手先拿的是右侧的这一堆,还是一样的,假设把它拿成了\(z\),如果\(z<R\),同上可以变成\(x<L,x<R\)的情况;如果\(y=R\),直接把左边拿完,就变成了\(R[i][j-1]\)的定义了,先手必败;如果\(z>R\),把左边那堆变成\(z-1\),同样递归处理。
  • \(L<x<R\)

    分析同上,\(L[i][j]=x+1\)。
  • \(x>L,x>R\)

    \(L[i][j]=x\)。还是一样的,假设先手把其中一堆拿成了\(z\)。如果\(z>L,R\),跟着先手拿成一样多的石子则又回到了这种情况。如果\(z<L,R\),则可以回到情况\(x<L,R\)。否则的话对应着把另外一堆变成\(z+1\)或者\(z-1\),对应着\(L<x<R\)和\(R<x<L\)两种情况。

而\(R[][]\)和\(L[][]\)是对称的,类似的求解即可。

那么最终只需要判断\(L[2][n]\)和\(a[1]\)是否相等即可判断胜负情况。

代码有点丑

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 1010
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,a[MAX],L[MAX][MAX],R[MAX][MAX];
int main()
{
int T=read();
while(T--)
{
n=read();
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=n;++i)L[i][i]=R[i][i]=a[i];
for(int len=2;len<=n;++len)
for(int i=1,j=i+len-1;j<=n;++i,++j)
{
int x=a[j],l=L[i][j-1],r=R[i][j-1];
if(x==r)L[i][j]=0;
else if((x>l&&x>r)||(x<l&&x<r))L[i][j]=x;
else if(r<x&&x<l)L[i][j]=x-1;
else L[i][j]=x+1;
x=a[i],l=L[i+1][j],r=R[i+1][j];
if(x==l)R[i][j]=0;
else if((x>l&&x>r)||(x<l&&x<r))R[i][j]=x;
else if(r<x&&x<l)R[i][j]=x+1;
else R[i][j]=x-1;
}
puts(a[1]==L[2][n]?"0":"1");
}
}

【BZOJ1413】[ZJOI2009]取石子游戏(博弈论,动态规划)的更多相关文章

  1. bzoj1413 [ZJOI2009]取石子游戏

    Description 在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从 ...

  2. 洛谷P2599||bzoj1413 [ZJOI2009]取石子游戏

    bzoj1413 洛谷P2599 根本不会啊... 看题解吧 #include<cstdio> #include<algorithm> #include<cstring& ...

  3. 【一本通提高博弈论】[ZJOI2009]取石子游戏

    [ZJOI2009]取石子游戏 题目描述 在研究过 Nim 游戏及各种变种之后,Orez 又发现了一种全新的取石子游戏,这个游戏是这样的: 有 n n n 堆石子,将这 n n n 堆石子摆成一排.游 ...

  4. POJ.1067 取石子游戏 (博弈论 威佐夫博弈)

    POJ.1067 取石子游戏 (博弈论 威佐夫博弈) 题意分析 简单的威佐夫博弈 博弈论快速入门 代码总览 #include <cstdio> #include <cmath> ...

  5. HDU.2516 取石子游戏 (博弈论 斐波那契博弈)

    HDU.2516 取石子游戏 (博弈论 斐波那契博弈) 题意分析 简单的斐波那契博弈 博弈论快速入门 代码总览 #include <bits/stdc++.h> #define nmax ...

  6. bzoj 1413 [ZJOI2009]取石子游戏

    1413: [ZJOI2009]取石子游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 747  Solved: 490[Submit][Statu ...

  7. vijos 1557:bzoj:1413: [ZJOI2009]取石子游戏

    Description 在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从 ...

  8. 【刷题】BZOJ 1413 [ZJOI2009]取石子游戏

    Description 在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从 ...

  9. 【BZOJ1413】取石子游戏(博弈,区间DP)

    题意:在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从最左或最右的一堆中 ...

随机推荐

  1. 【H5】直接拨打电话

    一般<a href="tel:400-663-5999">400-663-5999</a>实现. 而形如<a href="tel:*9204 ...

  2. 2017-2018-2 20155231《网络对抗技术》实验五: MSF基础应用

    2017-2018-2 20155231<网络对抗技术>实验五: MSF基础应用 实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 实验内容 (1)各种搜索技巧的应用 比如IP2L ...

  3. 20155302《网络对抗》Exp9 Web安全基础

    20155302<网络对抗>Exp9 Web安全基础 实验内容 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验过程 1.webgoat的安装启动 使用自己 ...

  4. WPF编程 ,TextBlock 显示百分数值的一种简单方法。

    原文:WPF编程 ,TextBlock 显示百分数值的一种简单方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/ ...

  5. 【调试】Core Dump是什么?Linux下如何正确永久开启?

    [调试]Core Dump是什么?Linux下如何正确永久开启?

  6. mybatis源码-解析配置文件(二)之解析的流程

    目录 1. 简介 2. 配置文件解析流程分析 2.1 调用 2.2 解析的目的 2.3 XML 解析流程 2.3.1 build(parser) 2.3.2 new XMLConfigBuilder( ...

  7. webVR全景图多种方案实现(pannellum,aframe,Krpano,three,jquery-vrview)

    前言 有一篇文章我说了H5实现全景图预览,全景视频播放的原理,有需要的小伙伴可以自行去看一下 今天我就拿出我的实践干货出来,本人实测实测过 需求 老板:我需要可以上传全景图片,然后手机网站上都可以36 ...

  8. 12、利用docker快速搭建Wordpress网站

    一.准备工作 结构图: 用户访问页面,Nginx将请求进行转发,如果请求的是php页面,则通过FastCGI转发给后端php进行处理:如果非php页面,则直接返回静态页面. 关键点: mysql.ph ...

  9. [转载] 相机越贵画质越好?聊聊CMOS设计

    似乎在很多人心目中,个位数机身就代表了品牌最强成像素质,这或许有“人不识货钱识货”的道理在作祟,但事实上如佳能1DX2或尼康D5,又或是索尼A9这种旗舰机真的就一定能代表本家的画质巅峰么?这一切都得从 ...

  10. CodeFirst从零搭建ASP.NETCore2.0

    没时间介绍了,废话不说先上车 以下所有扯淡都是建立在.NETCore2.0环境已经搭建好 右键解决方案>新建项目> 选择Web>ASP.NETCoreWeb应用程序(.NET Cor ...