博弈论基础

举报
兔老大 发表于 2021/04/23 00:04:56 2021/04/23
【摘要】 博弈论总结 什么是博弈论: 多人进行博弈,假设每个人都采取最优策略,一定有一个人胜出,在知道初态及规则的情况下,求解出 何人胜出的一类问题的理论及方法。 博弈论的一些性质 P点:必败点,N点:必胜点 (1)无法进行任何移动的局面(也就是terminal position)是P-position; (2)可以移动到P-position的局面是N-position;...

博弈论总结

什么是博弈论:

多人进行博弈,假设每个人都采取最优策略,一定有一个人胜出,在知道初态及规则的情况下,求解出

何人胜出的一类问题的理论及方法。

博弈论的一些性质

P点:必败点,N点:必胜点

1)无法进行任何移动的局面(也就是terminal position)是P-position

2)可以移动到P-position的局面是N-position

3)所有移动都导致N-position的局面是P-position

巴什博奕:

介绍:只有一堆n个物品,两个人轮流从中取物,规定每次最少取一个,最多取m个,最后取光者为

胜。

必定可以写成该式子 n=k*(m+1)+r

结论:若r=0,则先手必败,否则先手必胜。


  
  1. if(n % (m + 1) == 0)
  2. cout<<"后手必胜"<<endl;
  3. else
  4. cout<<"先手必胜"<<endl;

威佐夫博弈:

介绍:有两堆各若干的物品,两人轮流从其中一堆取至少一件物品,至多不限,或从两堆中同时取相同

件物品,规定最后取完者胜利。

结论:若两堆物品的初始值为(xy),且x<y,则另z=y-x

w=int[((sqrt5+1/2*z ];(中间为熟知的黄金分割比)

w=x,则先手必败,否则先手必胜。


  
  1. if(x > y)
  2. swap(x, y);
  3. int c = floor((y - x) * (sqrt(5) + 1) / 2);
  4. if(c == x)
  5. cout<<0<<endl;
  6. else
  7. cout<<1<<endl;

尼姆博奕:

介绍:有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取

光者得胜.

结论:n堆石子全部做异或运算,结果为0则为必败结果

SG函数:

首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非

负整数。例如mex{0,1,2,4}=3mex{2,3,5}=0mex{}=0

对于任意状态 x 定义 SG(x) = mex(F),其中F x 后继状态的SG函数值的集合(就是上述mex中的数

值)。最后返回值(也就是SG(X))为0为必败点,不为零必胜点。

进一步解释一下F,就是题意中给出的可以移动的次数。举个例子来说,一堆石子,每次只能拿13

57个,那么S数组就是1357

假如说是在一个游戏中有多个石子堆该怎么办了。我们只需要把对每个石子堆进行sg函数的调用,将得

到的所有的值进行异或。得出来的结果为0则该情形为必败态。否则为必胜态。


  
  1. int sg[MAXN];
  2. int f[MAXM]; //可以取走的石子个数
  3. bool Hash[MAXN];
  4. void getSG(int m)
  5. {
  6. memset(sg, 0, sizeof(sg));
  7. for (int i = 1; i < MAXN; i++) {//枚举石子的个数
  8. memset(Hash, false, sizeof(Hash));
  9. for (int j = 0; j < m && f[j] <= i; j++)
  10. Hash[sg[i-f[j]]] = true;//枚举每次拿走的个数并标记
  11. for (int j = 0; j < MAXN; j++) {
  12. if (!Hash[j]) {
  13. sg[i] = j; //找到这个F[](该状态可以达到的状态)中不存在的最小的数
  14. break;
  15. }
  16. }
  17. }
  18. }
  19. //例题:hdu1847
  20. int main()
  21. {
  22. int n, num = 1;
  23. for (int i = 0; i < MAXM; num <<= 1, i++)
  24. f[i] = num;//这里的F数组就是可以移动的步数,每次都是2的幂次
  25. getSG(MAXM);
  26. while (cin >> n)
  27. {
  28. if (sg[n])
  29. cout << "Kiki" << endl;
  30. else
  31. cout << "Cici" << endl;
  32. }
  33. return 0;
  34. }

 

 

文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有,如需转载,请联系作者。

原文链接:fantianzuo.blog.csdn.net/article/details/102688773

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。