bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)
1188: [HNOI2007]分裂游戏
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 733 Solved: 451
[Submit][Status][Discuss]
Description
聪
聪和睿睿最近迷上了一款叫做分裂的游戏。 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有
p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子。标号为 i,j,k, 并要保证 i < j , j < = k
且第 i 个瓶子中至少要有 1 颗巧克力豆,随后这个人从第 i 个瓶子中拿走一颗豆 子并在 j,k 中各放入一粒豆子(j 可能等于 k)
。如果轮到某人而他无法按规则取豆子,那么他将输 掉比赛。胜利者可以拿走所有的巧克力豆!
两人最后决定由聪聪先取豆子,为了能够得到最终的巧克力豆,聪聪自然希望赢得比赛。他思考
了一下,发现在有的情况下,先拿的人一定有办法取胜,但是他不知道对于其他情况是否有必胜
策略,更不知道第一步该如何取。他决定偷偷请教聪明的你,希望你能告诉他,在给定每个瓶子
中的最初豆子数后是否能让自己得到所有巧克力豆,他还希望你告诉他第一步该如何取,并且为 了必胜,第一步有多少种取法? 假定 1 < n
< = 21,p[i] < = 10000
Input
输入文件第一行是一个整数t表示测试数据的组数,接下来为t组测试数据(t<=10)。每组测试数据的第一行是瓶子的个数n,接下来的一行有n个由空格隔开的非负整数,表示每个瓶子中的豆子数。
Output
对
于每组测试数据,输出包括两行,第一行为用一个空格两两隔开的三个整数,表示要想赢得游戏,第一步应该选取的3个瓶子的编号i,j,k,如果有多组符合要
求的解,那么输出字典序最小的一组。如果无论如何都无法赢得游戏,那么输出用一个空格两两隔开的三个-1。第二行表示要想确保赢得比赛,第一步有多少种不
同的取法。
Sample Input
4
1 0 1 5000
3
0 0 1
Sample Output
1
-1 -1 -1
0
HINT
Source
【思路】
SG函数,博弈
看作是一排n个位置,每个位置有一个或零个石子,因为偶数个石子的sg抑或后为0,所以把p[i]为奇数的看作是一个石子,偶数的看作是零个石子。
考虑简化后的题目,一颗石子在i会转移到一颗石子在j一颗石子在k的子状态,所以i局面的后继即为jk局面,此时可以记忆化搜索sg值。
真神奇 < _ <
【代码】
#include<cstdio>
#include<cstring>
using namespace std; const int N = ; int n,a[N],sg[N],ans,tot; int dfs(int x) {
if(sg[x]!=-) return sg[x];
if(x==n) return sg[x]=;
bool vis[];
memset(vis,,sizeof(vis));
for(int i=x+;i<=n;i++)
for(int j=i;j<=n;j++)
vis[dfs(i)^dfs(j)]=;
for(int i=;;i++)
if(!vis[i]) return sg[x]=i;
} int main() {
int T;
scanf("%d",&T);
while(T--) {
memset(sg,-,sizeof(sg));
ans=tot=;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<=n;i++)
if(a[i]&) ans^=dfs(i);
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
for(int k=j;k<=n;k++) {
if((ans^dfs(i)^dfs(j)^dfs(k))) continue;
++tot;
if(tot==) printf("%d %d %d\n",i-,j-,k-);
}
if(!tot) printf("-1 -1 -1\n");
printf("%d\n",tot);
}
return ;
}
bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)的更多相关文章
- bzoj 1188 [HNOI2007]分裂游戏 SG函数 SG定理
[HNOI2007]分裂游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1394 Solved: 847[Submit][Status][Dis ...
- bzoj 1188 : [HNOI2007]分裂游戏 sg函数
题目链接 给n个位置, 每个位置有一个小球. 现在两个人进行操作, 每次操作可以选择一个位置i, 拿走一个小球.然后在位置j, k(i<j<=k)处放置一个小球. 问你先进行什么操作会先手 ...
- [BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】
题目链接:BZOJ - 1188 题目分析 我们把每一颗石子看做一个单个的游戏,它的 SG 值取决于它的位置. 对于一颗在 i 位置的石子,根据游戏规则,它的后继状态就是枚举符合条件的 j, k.然后 ...
- BZOJ 1188 / Luogu P3185 [HNOI2007]分裂游戏 (SG函数)
题意 有n个格子,标号为0 ~ n-1,每个格子上有若干石子,每次操作可以选一个0 ~ n-2的格子上的一颗石子,分裂为两颗,然后任意放在后面的两个格子内,这两个格子可以相同.求使先手必胜的第一步的方 ...
- BZOJ 1188: [HNOI2007]分裂游戏(multi-nim)
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1386 Solved: 840[Submit][Status][Discuss] Descripti ...
- BZOJ 1188 [HNOI2007]分裂游戏
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1188 学习SG函数的过程中,我先看了一篇叫做 <2008-贾志豪-组合数学略述... ...
- BZOJ1188 [HNOI2007]分裂游戏(SG函数)
传送门 拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数.看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做. 这道题需要奇特的模型转换.即把每一个石子当做一堆石子,且原来在第i堆 ...
- BZOJ P1188 HNOI2007 分裂游戏——solution
题目描述: (<--这个) 组合游戏,——把每个石头看做一个游戏, Multi_game——消去i上的石子后,,k上的游戏又多了一个: 于是就套用multi_game的模型即可 求解SG函数时, ...
- BZOJ 1874 取石子游戏 - SG函数
Description $N$堆石子, $M$种取石子的方式, 最后取石子的人赢, 问先手是否必胜 $A_i <= 1000$,$ B_i <= 10$ Solution 由于数据很小, ...
随机推荐
- 数据库性能高校:CPU使用过高(上)
CPU使用率过高问题很容易被发现,但是诊断却不是很容易.CPU使用过高很多时候会成为其它问题的替罪羊,所以在确认和故障诊断时要抽丝剥茧. 调查CPU压力 三个主要的工具:性能监视器,SQLTrace, ...
- ios专题 - 单例模式的实现
[原创]http://www.cnblogs.com/luoguoqiang1985 单例模式是什么? 一个类只有一个实例. ----------------------- 这样做有什么好处? 在我的 ...
- hdoj(3790) 最短路径
最短路径问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- jQuery动态添加的元素中处理字符串溢出后在指定字符数后添加省略号
"+[jsonData[i].questitle.lenth>40?jsonData[i].questitle.substring(0,40)+"...":json ...
- thinkphp我掉下的一些坑
1.数据库连接,需要连接没有数据表前缀 如下,第二个参数必须为null,我之前写的是'',结果给我默认加了前缀 $User = M('User',Null,'DB_CONFIG2'); 2.AJAX获 ...
- php开源项目学习二次开发的计划
开源项目: cms 国内 dedecms cmstop 国外 joomla, drupal 电商 国内 ecshop 国外 Magento 论坛 discuz 博客 wordpress 学习时 ...
- 搭建laravel5全面教学,爬坑(windows下)。
1.首先下载屌比的Composer 2.然后下载composer.phar 3.然后下载最新版Laravel框架 4.将下载下来的laravel压缩包扔到htdocs目录下(扔到别的目录没试过) 5. ...
- [CSS]列表属性(List)
CSS 列表属性(List) 属性 描述 CSS list-style 在一个声明中设置所有的列表属性. 1 list-style-image 将图象设置为列表项标记. 1 list-style- ...
- Android内的生命周期整理
1. Android App的生命周期: 2. Application的生命周期: 3. Activity的生命周期: 3.1 Fragment的生命周期: 4. Service的生命周期:5. Br ...
- Ubuntu 在右键快捷菜单中添加“Open in Terminal”
操作步骤翻译如下: 1.打开一个Terminal(ctrl+alt+t),输入如下指令 sudo apt-get install nautilus-open-terminal 2.使用以下指令来重启N ...