【BZOJ1413】取石子游戏(博弈,区间DP)
题意:在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的:
有n堆石子,将这n堆石子摆成一排。游戏由两个人进行,两人轮流操作,每次操作者都可以从最左或最右的一堆中取出若干颗石子,
可以将那一堆全部取掉,但不能不取,不能操作的人就输了。
Orez问:对于任意给出一个初始一个局面,是否存在先手必胜策略。
T≤10 n≤1000 每堆的石子数目≤1e9
思路:From http://www.cnblogs.com/zcwwzdjn/archive/2012/05/26/2519685.html
在尝试SG函数, 区间DP无果后, 在Discuss的诱导下注意到对于一段区间[L, R], 若L+1到R的石子数固定, 那么使得在这段区间上先手必败的a[L]有且仅有一个.
这个性质灰常给力啊. 于是可以YY一个状态出来. 设left[i][j]表示, 在[i, j]区间的左边加上left[i][j]这个数后先手必败, right[i][j]的定义类似. 那么最后我们只用看left[2][n]是否等于a[1]就可以了.
接着我们想办法来算left[i][j]. right[i][j]可以类似的求出.
设L = left[i][j - 1], R = right[i][j - 1], X = a[j]. 通过下面的分析我们可以发现left[i][j]只和L, R, X三个数有关.
首先, 最容易想到的是, R = X的情况, 这时[i, j]这段区间已经先手必败, 那么left[i][j] = 0.
接着, 我们可以发选当X < L且X < R时, left[i][j] = X. 在这种局面下, 若先手在一侧取走一些石子, 那么后手在另外一边取走相同数量的石子就可以了.
然后我们根据L和R的关系分类讨论一下.
若L > R, 我们考虑R < x <= L的情况, 这时left[i][j] = X - 1. X - 1 = R时是很轻松的, 因为先手不能把右侧石堆取到R, 所以后手保证每次取之后两堆石子相同就可以了. 当X - 1 > R时, 若先手把左边取到R, 那么后手把右边取到R + 1就可以了; 若先手取到R + 1, 那么后手取到R + 2; 以此类推.
若L < R, 我们考虑L <= X < R的情况, 这时left[i][j] = X + 1. 这个和上面类似.
最后的一种情况, x > L且x > R. 其实left[i][j] = X. 若L = R, 没啥说的; 若L和R不等, 我们不妨设L > R, 这时若先手把右边取到L, 那么后手需要把左边取到L - 1, 这时如果先手跟着后手走, 那么后手一颗一颗石子取就赢了; 若先手把左边取到R, 那么后手需要把右边取到R + 1, 这种情况似乎一定成立, 因为后手不会主动走到R + 1, 除非对方走到了R.
反正这个分析无比蛋疼...首先状态的定义非常奇葩, 具有一定的启发性(因为这题灰常隐蔽的一个性质)...然后分情况讨论无比痛苦...考场上还是找规律吧...
分类讨论的核心在于要找出后手的必胜策略.
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
typedef long long ll;
using namespace std;
#define N 1100
#define oo 10000000
#define MOD 1000000007 int l[N][N],r[N][N],a[N]; int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=n;i++) l[i][i]=r[i][i]=a[i];
for(int len=;len<=n;len++)
for(int i=;i<=n-len+;i++)
{
int j=i+len-;
int p=l[i][j-];
int q=r[i][j-];
int x=a[j];
if(x==q) l[i][j]=;
else if((x<p&&x<q)||(x>p&&x>q)) l[i][j]=x;
else if(p<q) l[i][j]=x+;
else l[i][j]=x-;
p=r[i+][j];
q=l[i+][j];
x=a[i];
if(x==q) r[i][j]=;
else if((x<p&&x<q)||(x>p&&x>q)) r[i][j]=x;
else if(p<q) r[i][j]=x+;
else r[i][j]=x-;
}
if(n==) printf("1\n");
else printf("%d\n",(r[][n-]!=a[n]));
}
return ;
}
【BZOJ1413】取石子游戏(博弈,区间DP)的更多相关文章
- hdu 2516 取石子游戏 (博弈)
取石子游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- NOIP2007 矩阵取数游戏(区间DP)
传送门 这道题第一眼看上去可能让人以为是贪心……不过贪心并不行,因为每次的操作是有2的幂次方的权值的.这样的话直接每次贪心最小的就目光短浅.所以那我们自然想到了DP. 据说这是一道很正常的区间DP? ...
- 洛谷 P1005 矩阵取数游戏 (区间dp+高精度)
这道题大部分时间都在弄高精度-- 还是先讲讲dp吧 这道题是一个区间dp,不过我还是第一次遇到这种类型的区间dp f[i][j]表示取了数之后剩下i到j这个区间的最优值 注意这里是取了i之前和j之后的 ...
- luogu1005矩阵取数游戏题解--区间DP
题目链接 https://www.luogu.org/problemnew/show/P1005 分析 忽然发现这篇题解好像并没有什么意义...因为跟奶牛零食那道题一模一样,博主比较懒如果您想看题解的 ...
- POJ 1067 取石子游戏 [博弈]
题意:威佐夫博弈. 思路:看了很多证明都没看懂.最后决定就记住结论好了. 对于所有的奇异局面(必败局),有通项公式 Pi = (a, b), (a = i * [(sqrt(5) + 1) / 2], ...
- 计蒜客 取数游戏 博弈+dp
题目链接 取数游戏 思路:dp(x, y)表示先手在区间[x, y]能取得的最大分数.当先手取完,就轮到后手去,后手一定会选择当前能令他得到最大分数的策略,其实当先手在[x, y]区间两端取走一个数, ...
- 【BZOJ1413】[ZJOI2009]取石子游戏(博弈论,动态规划)
[BZOJ1413][ZJOI2009]取石子游戏(博弈论,动态规划) 题面 BZOJ 洛谷 题解 神仙题.jpg.\(ZJOI\)是真的神仙. 发现\(SG\)函数等东西完全找不到规律,无奈只能翻题 ...
- HDU 2516 取石子游戏(斐波那契博弈)
取石子游戏 Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- 取石子游戏(hdu1527 博弈)
取石子游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
随机推荐
- mysql运维-二进制日志BINARY LOG清理
1.1 方法1:PURGE MASTER LOGS 语法: PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetim ...
- 将数组转化为json字符串(不使用json_encode函数)
将数组转化为json字符串(不使用json_encode函数) public function arrayToJson($arr,$jsonStr=''){ $jsonStr.='{'; foreac ...
- C语言实例解析精粹学习笔记——44(冒泡排序)
冒泡排序,从序列的最后一个元素与前一个元素比较大小,如果R[n-1]>R[n]则交换两个元素的位置(R[0]作为临时存放区)将最小的数据交换到R[1],第二次循环将第二小的数交换到R[2].通过 ...
- Android开发——常见的内存泄漏以及解决方案(一)
0. 前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52333954 Android的内存泄漏是Android开发领域永恒的 ...
- 2 Model层 - 模型查询
1.简介 查询集表示从数据库中获取的对象集合 查询集可以含有零个.一个或多个过滤器 过滤器基于所给的参数限制查询的结果 从Sql的角度,查询集和select语句等价,过滤器像where和limit子句 ...
- HDU 5739 Fantasia 双连通分量 树形DP
题意: 给出一个无向图,每个顶点有一个权值\(w\),一个连通分量的权值为各个顶点的权值的乘积,一个图的权值为所有连通分量权值之和. 设删除顶点\(i\)后的图\(G_i\)的权值为\(z_i\),求 ...
- day21&22&23:线程、进程、协程
1.程序工作原理 进程的限制:每一个时刻只能有一个线程来工作.多进程的优点:同时利用多个cpu,能够同时进行多个操作.缺点:对内存消耗比较高当进程数多于cpu数量的时候会导致不能被调用,进程不是越多越 ...
- 【Python】locust框架接口性能测试(一)
本人工作中主要对接口与web进行性能测试,而接口测试主要为http协议接口和webservice接口,本文主要对locust框架http接口测试先进行简单介绍. 1.测试需求 对某系统登录接口进行测试 ...
- 【LoadRunner】对摘要认证的处理
近期项目中,进行http协议的接口性能测试过程中,需要进行登录接口的摘要认证,分享一下测试经验. 测试准备 测试工具:LoadRunner11 测试类型:接口测试--某系统登录接口 步骤 根据系统接口 ...
- Windows下MySQL8.0.11.0安装教程
1.mysql下载地址:https://dev.mysql.com/downloads/installer/ 2.下载安装MySQL 8.0.11.0 https://cdn.mysql.com//D ...