HDU 1524 A Chess Game (SG函数模板题)
来源:互联网 发布:数据库体育信息管理 编辑:程序博客网 时间:2024/06/02 16:53
题意:在一个有向无环图上有n个顶点,每一个顶点都只有一个棋子,有两个人,每次根据这个图只能将任意一颗
棋子移动一步
,如果到某一步玩家不能移动时,那么这个人就输.
分析:本题是最典型的有向无环图的博弈,利用dfs把所有顶点的SG值都计算出来,然后对每个棋子的SG值进行
异或运算,如果为0就是先手必败,否则就是先手必胜.
如果某个人移动到出度为0的顶点,那么他必败,在这里首先介绍一下什么是SG函数.
Sprague-Grudy定理:
令N = {0, 1, 2, 3, ...} 为自然数的集合。Sprague-Grundy 函数给游戏中的每个状态分配了一个自然数。
结点v的Grundy值等于没有在v的后继的Grundy值中出现的最小自然数.
形式上:给定一个有限子集 S ⊂ N,令mex S(最小排斥值)为没有出现在S中的最小自然数。定义mex(minimal
excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}
=3、mex{2,3,5}=0、mex{}=0。
对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Garundy函数g如下:g(x)=mex{ g(y) | y是x
的后继 }。
性质:
(1)所有的终结点所对应的顶点,其SG值为0,因为它的后继集合是空集——所有终结点是必败点(P点即先
手必败点)。
(2)对于一个g(x)=0的顶点x,它的所有后继y都满足g(y)!=0——无论如何操作,从必败点(P点)都只能进
入必胜点(N点)//对手走完又只能把N留给我们。
(3)对于一个g(x)!=0的顶点,必定存在一个后继点y满足g(y)=0——从任何必胜点(N点)操作,至少有一
种方法可以进入必败点(P点)//就是那种我们要走的方法。
而求整个SG函数值的过程就是一个对有向无环图进行深搜过程.
其次解释一下为什么要异或。
这需要了解下Nim博弈,事实上我们可以利用SG函数转成Nim博弈。
棋子移动一步
,如果到某一步玩家不能移动时,那么这个人就输.
分析:本题是最典型的有向无环图的博弈,利用dfs把所有顶点的SG值都计算出来,然后对每个棋子的SG值进行
异或运算,如果为0就是先手必败,否则就是先手必胜.
如果某个人移动到出度为0的顶点,那么他必败,在这里首先介绍一下什么是SG函数.
Sprague-Grudy定理:
令N = {0, 1, 2, 3, ...} 为自然数的集合。Sprague-Grundy 函数给游戏中的每个状态分配了一个自然数。
结点v的Grundy值等于没有在v的后继的Grundy值中出现的最小自然数.
形式上:给定一个有限子集 S ⊂ N,令mex S(最小排斥值)为没有出现在S中的最小自然数。定义mex(minimal
excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}
=3、mex{2,3,5}=0、mex{}=0。
对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Garundy函数g如下:g(x)=mex{ g(y) | y是x
的后继 }。
性质:
(1)所有的终结点所对应的顶点,其SG值为0,因为它的后继集合是空集——所有终结点是必败点(P点即先
手必败点)。
(2)对于一个g(x)=0的顶点x,它的所有后继y都满足g(y)!=0——无论如何操作,从必败点(P点)都只能进
入必胜点(N点)//对手走完又只能把N留给我们。
(3)对于一个g(x)!=0的顶点,必定存在一个后继点y满足g(y)=0——从任何必胜点(N点)操作,至少有一
种方法可以进入必败点(P点)//就是那种我们要走的方法。
而求整个SG函数值的过程就是一个对有向无环图进行深搜过程.
其次解释一下为什么要异或。
这需要了解下Nim博弈,事实上我们可以利用SG函数转成Nim博弈。
Nim问题模型
然后解决它的思路是这样的
那么知道Nim博弈如何解决,我们如何将SG巧妙第转换为nim呢?
以上内容均来自《挑战程序设计竞赛》
所以,问题就解决啦,先DFS出SG函数(注意要用记忆化搜索哦,否则很容易超时),然后算出所有SG的异或值即可。
#include<iostream>#include<vector>#include<cstdio>using namespace std;const int maxn=1005;vector<int>G[maxn];int n,dp[maxn];int dfs(int u){ if(dp[u]!=-1) return dp[u]; int vis[maxn]; fill(vis,vis+n,0); for(int i=0;i<G[u].size();i++) { int v=G[u][i]; dp[v]=dfs(v); vis[dp[v]]=1; } for(int i=0;i<n;i++) if(vis[i]==0) return i;}int main(){ //freopen("in.txt","r",stdin); while(cin>>n) { for(int i=0;i<=n;i++) G[i].clear(),dp[i]=-1;//清空邻接矩阵以及初始化记忆化数组 for(int i=0;i<n;i++) { int m,x; cin>>m; while(m--) { cin>>x; G[i].push_back(x);//用邻接表存有向图 } } int q; while(cin>>q,q) { int x,f=0; while(q--) { cin>>x; f^=dfs(x);//算出所有数异或的结果 } if(f) cout<<"WIN"<<endl; else cout<<"LOSE"<<endl; } } return 0;}
0 0
- HDU 1524 A Chess Game (SG函数模板题)
- HDU 1524 A Chess Game 【SG函数】
- HDU 1524 A Chess Game(SG函数)
- 【POJ2425】A Chess Game 博弈,SG函数,裸题,模板题
- HDU ACM 1524 A Chess Game->博弈(SG函数)
- HDU 1524 A Chess Game [SG函数]【博弈】
- HDU 1524 - A Chess Game(SG)
- hdu 1524 A Chess Game (SG)
- HDU 1524 A Chess Game(SG博弈)
- HDOJ 1524 A Chess Game SG函数
- hdu 1524 A Chess Game 博弈之,SG函数简单题
- hdu 1524 A Chess Game SG函数(有向无环图-拓扑图)博弈 (二维) + dfs(模板)
- HDU-1524-A Chess Game && POJ-2425 【sg】
- pku 2425 A Chess Game(SG函数)
- poj 2425 A Chess Game (sg函数)
- 【PKU】A Chess Game(sg函数)
- 【POJ 2425】A Chess Game SG函数
- sg函数_____A Chess Game( hdu 2425 )
- class not found exception
- 文件操作编程之文件读写
- 采用非常规方法(非gprecoverseg) 恢复greenplum数据库
- react-native试玩(22)-文本输入框
- Java出现No enclosing instance of type E is accessible. Must qualify the allocation with an enclosing
- HDU 1524 A Chess Game (SG函数模板题)
- 对C++中const的总结
- 《编程导论(Java)·11排序》
- 研二:机遇(上)
- 文件操作编程之复制移动删除
- Bitmap处理 之四缓存位图
- hdu 3879 Base Station【最大权闭合图】
- react-native试玩(23)-触摸高亮
- 《数据挖掘导论》学习笔记(第1-2章)