BZOJ1188 [HNOI2007]分裂游戏(SG函数)
2016-03-07 01:15
344 查看
传送门
拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数。看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做。
这道题需要奇特的模型转换。即把每一个石子当做一堆石子,且原来在第i堆的石子(从0开始标号)的石子个数为n-i-1,这样题目就转化成了每次取一堆石子,并放回两个比这一堆的石子个数少的石堆。这样,我们就可以有序的递推sg函数值了。
即:sg(i)=mex({sg[j] xor sg[k]})
其中j≤i且k≤i
拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数。看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做。
这道题需要奇特的模型转换。即把每一个石子当做一堆石子,且原来在第i堆的石子(从0开始标号)的石子个数为n-i-1,这样题目就转化成了每次取一堆石子,并放回两个比这一堆的石子个数少的石堆。这样,我们就可以有序的递推sg函数值了。
即:sg(i)=mex({sg[j] xor sg[k]})
其中j≤i且k≤i
#include <cstdio> #define MAXN 25 int sg[MAXN], n, a[MAXN]; bool used[MAXN]; void init() { for(int i = 1; i < MAXN; ++ i) { for(int j = 0; j < MAXN; ++ j)used[j] = 0; for(int j = 0; j < i; ++ j) for(int k = 0; k <= j; ++ k) used[sg[j]^sg[k]] = 1; for(int j = 0; j < MAXN; ++ j) if(!used[j]) { sg[i] = j; break; } } } int main() { init(); int T; scanf("%d", &T); while(T --) { scanf("%d", &n); int ans = 0, cnt = 0; for(int i = 0; i < n; ++ i) { scanf("%d", &a[i]); if(a[i] & 1) ans ^= sg[n-i-1]; } for(int i = 0; i < n; ++ i) { if(!a[i]) continue; for(int j = i+1; j < n; ++ j) { if(!a[j]) continue; for(int k = j; k < n; ++ k) { if(!a[k]) continue; if((ans ^ sg[n-i-1] ^ sg[n-j-1] ^ sg[n-k-1]) == 0) { if(!cnt) printf("%d %d %d\n", i, j, k); ++ cnt; } } } } if(!cnt) puts("-1 -1 -1"); printf("%d\n", cnt); } return 0; }
相关文章推荐
- BZOJ1188 [HNOI2007]分裂游戏(SG函数)
- 硬件之SPI时序
- 我开源了一个ios应用,你们拿去随便玩
- UIScrollView
- 长理ACM 7-密码破译(闫博钊)
- 在虚拟机间 NFV 应用上使用采用 DPDK 的 Open vSwitch*
- 第二周作业
- 软件工程的认识
- hibernate3与ehcache-2.8.3配合使用,在多个SessionFactory实例的情况下出现“Another unnamed CacheManager already exists in the same VM”问题
- PAT 1009 Product of Polynomials (25)
- andorid_activity简单的入门
- UIPikerView的属性
- 在硅谷初创公司怎么找投资人
- 硬件之IIC时序
- ns-3快速上手-开发环境搭建篇(译)
- 1376 最长递增子序列的数量(dp+线段树优化)
- School Regional Team Contest, Saratov, 2011-F. Spiders-求树直径
- Logistic Regression的一些认识
- cf#211-D. Renting Bikes-二分
- [CodeForces 607A]Chain Reaction[DP]