人类的本质是什么呢?复读机?鸽子?
博弈问题是很有意思的一类题目
我讲的可能不是很明白,但题目都不难建议自己思考
组合游戏的特点:
1.两个人博弈,轮流做出最优决策
2.玩家在每个时刻做出的决策都是能预测到的,是一个确定的集合
3.每种状态可能有多种方式到达,但同一种状态不能在一次游戏中重复到达,且没有平局的情况
4.只要能进行决策,就一定要决策,不能跳过这个回合
SG组合游戏
我们把每种状态抽象成一个点,在起点有一颗棋子,两个人选取最优策略轮流对这颗棋子进行移动,最后不能移动棋子的人失败
显然这张图是一个有向无环图
(以下用集合的名称代指集合内的点)
有向图的核
给定一张DAG图<V,E>,如果V的一个点集S满足:
1.S是独立集
2.集合V-S中的点可以通过一步到达集合S中的点
那么S是图V的一个核
结论:核内节点对应SG组合游戏的必败态
Alice把棋子从S移动到V-S
然后Bob又通过一步把棋子从V-S移动到了S
Alice像是被支配了一样,被迫把棋子移动到了没有出度的必败节点,Bob胜利
说多了也没什么用,还是看题吧
默认Alice先手,Bob后手
注意,本文讨论的先手后手是针对状态而言的,而不是整局游戏
POJ 2368 Buttons (巴什博弈)
题面:
两个人玩游戏,有n个石子,两个人轮流取,每次取[1,L]个石子,取走最后一个石子的人胜利。假设两人秃顶聪明,问L为何值时第二个人必胜,输出L的最小值
题解:
如果(L+1)是n的约数,那么Bob必胜
Alice取了x个石子,Bob取L+1-x个石子..
发现按照这个策略取下去,Bob就赢了
Bob总能使这一轮石子的数量减少t+1个
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 100010 6 #define ll long long 7 #define ull unsigned long long 8 using namespace std; 9 10 const int inf=0x3f3f3f3f; 11 int n; 12 int gint() 13 { 14 int ret=0,fh=1;char c=getchar(); 15 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 16 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 17 return ret*fh; 18 } 19 20 int main() 21 { 22 scanf("%d",&n); 23 int i,j,sq=(int)sqrt(n),ans=inf; 24 if(n%2==0&&n/2>=3) ans=min(ans,n/2); 25 for(i=3;i<=sq;i++) 26 { 27 if(n%i==0) 28 { 29 ans=min(ans,i); 30 if(n/i>=3) ans=min(ans,n/i); 31 } 32 } 33 if(n>=3) ans=min(ans,n); 34 printf("%d\n",ans-1); 35 return 0; 36 }