博弈论 真的很有趣  ,回想起 前两天多校一道题的题解 所有不公平的游戏都存在必胜的玩法

 与人斗其乐无穷  https://vjudge.net/contest/241983#overview 博弈论专题

一)巴什博奕(Bash Game):有n个石头,Alice和Bob轮流取石头,每次取的石头不能超过m个,Alice开始取,最后取完的赢,两个人都是以最优的方案取,求最终赢的是谁

假设 n=m+1个,Alice 先取,无论她取多少个(>=1),Bob 都能一次性把剩下的取完,so ? Alice必输

情况就可以推广变成 如果 n= (m+1)*k  也就是 n%(m+1)==0 时,Alice 必输 ,反之 Alice 必赢

代码的话 实现很简单  hdu2188  hdu2149

 1  #include<cstdio>
 2 int main(){
 3     int t,n,m;
 4     scanf("%d",&t);while(t--){
 5         scanf("%d%d",&n,&m);
 6         if(n%(m+1)==0)printf("Bob\n");
 7         else printf("Alice\n");
 8     }
 9     return 0;
10 }

View Code

二)威佐夫博奕(Wythoff Game):有两堆石头,Alice和Bob轮流从某一堆取任意多的石头,或者从两堆中取相同多的石头,每次至少取一个石头, Alice开始取,最后取完的赢,两个人都是以最优的方案取,求最终赢的是谁(hdu 1846  hdu1527  51NOd1185)

就首先引入奇异局势,也就是当面临其一局势的状态必输。 比如(0,0)就是一个奇异局势,面临这种情况必输。  接下来的我就不懂了。。。。- = .=    十分钟前 ,我现在模拟了几组,懂了

前几个奇异局势有(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20) ...

性质就是每个自然数都会出现在一个且唯一的一个奇异局势里面 ,非奇异局势可以经过适当操作转化为奇异局势

两个数 不是奇异局势 就是 非奇异局势  ,当Alice面对奇异局势时,必输,反之,必赢

不是很懂的话 随便想两个数 模拟试试 多试几组就好了

三)尼姆博弈

有三堆石头,Alice和Bob轮流从其中一堆中取任意多的石头,每次至少取一个石头, Alice开始取,最后取完的赢,两个人都是以最优的方案取,求最终赢的是谁

奇异局势:第一个奇异局势是(0,0,0),面对这种情况的一定输。

设有a,b,c三堆石头,当a^b^c == 0时就是奇异局势,必输。
非奇异局势一定能变为奇异局势,奇异局势一定能变成非奇异局势。
证明:
当a^b^c != 0时,a+b+c != 0,即还有石头。
令a^b = x1,a^c = x2,b^c = x3,一定会存在至少下面的一种情况:
x1 < c,x2 < b,x3 < a。
假设x1 < c ,令c‘ =c – (c – x1) = x1,
得a^b^c’ == 0。
即非奇异局势变为奇异局势。

当a^b^c == 0 时,即a^b = c
只需要变成其中的任意一个数就可以当a^b != c。
即奇异局势变为非奇异局势。
由于(0,0,0)是最终得到的奇异局势,并且没有石头可取,所以面对a^b^c== 0的状态必输。

就异或为零和不为零情况就是了

http://acm.hdu.edu.cn/showproblem.php?pid=1907   多组输入 一个棋盘上黑白的位置 问谁嬴谁输 不懂为啥得 a-b-1 ???

走子方式,于是我们通过sg函数的定义,爆出sg函数值就发现sg函数值就是两个棋子的距离的绝对值减1.其实这个还是可以理解的,因为我们看当两个棋子相邻的时候,已经是一个必败态了。 ???

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
int main()
{int n,m,a,b;while(scanf("%d%d",&n,&m)!=EOF){int cnt =0,flag =0;for(int i=0;i< n;i++){scanf("%d%d",&a,&b);if(a < b)std::swap(a,b);if(a > 1)flag++;cnt ^= abs(a-b-1);//???
        }printf(cnt==0 ?"BAD LUCK!\n":"I WIN!\n");}return 0;
}

View Code

 SG函数

SG函数可以看成各个Nim游戏的和,将问题分成各种Nim问题,从而简化了问题。

例如:有三堆石头,每次能取的数量为斐波拉系数,即只能取1,2,3,5,8,13,21……这些石头的数量。

定义mex运算:表示最小的不属于这个集合的数。例如:mex{0,1,2,3} = 4、mex{0,1,3,4,5} = 2、mex{} = 0

对于任意的x,Sg(x) = mex{S},S为x的后继状态数值的集合,假设有三个状态Sg(a)、Sg(b)、Sg(c)。那么Sg(x) = mex{Sg(a),Sg(b),Sg(c)}。

设有三堆石头为x、y、z这三堆。那么只要判断Sg(x)^Sg(y)^Sg(z) == 0就行,当成立时就说明面对的是奇异局势,必输,反正必赢。

/* 摘自jumping_frog 博客

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

mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Grundy函数g如下:g(x)=mex{ g(y) | y是x的后继},这里的g(x)即

sg[x]。

例如:取石子问题,有1堆n个的石子,每次只能取{1,3,4}个石子,先取完石子者胜利,那么各个数的SG值为多少?

sg[0]=0,f[]={1,3,4},

x=1时,可以取走1-f{1}个石子,剩余{0}个,mex{sg[0]}={0},故sg[1]=1;

x=2时,可以取走2-f{1}个石子,剩余{1}个,mex{sg[1]}={1},故sg[2]=0;

x=3时,可以取走3-f{1,3}个石子,剩余{2,0}个,mex{sg[2],sg[0]}={0,0},故sg[3]=1;

x=4时,可以取走4-f{1,3,4}个石子,剩余{3,1,0}个,mex{sg[3],sg[1],sg[0]}={1,1,0},故sg[4]=2;

x=5时,可以取走5-f{1,3,4}个石子,剩余{4,2,1}个,mex{sg[4],sg[2],sg[1]}={2,0,1},故sg[5]=3;

以此类推.....

x         0  1  2  3  4  5  6  7  8....

sg[x]      0  1  0  1  2  3  2  0  1....

计算从1-n范围内的SG值。

f(存储可以走的步数,f[0]表示可以有多少种走法)

f[]需要从小到大排序

1.可选步数为1~m的连续整数,直接取模即可,SG(x) = x % (m+1);

2.可选步数为任意步,SG(x) = x;

3.可选步数为一系列不连续的数,用getSG()计算

*/

不懂i  SG函数  先放着 过段时间再来看  如果是费波纳茨序列的话 只需数组开16 第十六个费波纳茨数就1196

打表  和  dfs

// 获得SG数组函数模板,t代表f数组的个数,n代表要求的sg数组上限
// f数组就是能取的个数(对于此题就是Fibonacci数列
// 有时,对于t已知就不需要单独传参
void get_sg(int t,int n)
{int i,j;memset(sg,0,sizeof(sg));for(i=1;i<=n;i++){memset(mex,0,sizeof(mex));// 对于属于g(x)后继的数置1for( j=1 ;j<=t && fib[j]<=i ;j++ )mex[sg[i-fib[j]]]=1;// 找到最小不属于该集合的数for( j=0 ; j<=n ; j++ )if(!mex[j])break;sg[i] = j;}
}

View 打表 Code

//注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍
//n是集合s的大小 S[i]是定义的特殊取法规则的数组
int s[N],sg[N],n;
bool vis[N];
int dfs_SG(int x){if(sg[x] != -1)return sg[x];memset(vis,0,sizeof(vis));for(int i = 0; i < n; ++i){if(x >= s[i]){dfs_SG(x-s[i]);vis[sg[x-s[i]]] = 1;}}for(int i = 0;; ++i){if(!vis[i]){e = i;return sg[x] = i;}}
}

View dfs Code

#include <bits/stdc++.h> // hdu 1848
using namespace std;
const int N = 1010;
int sg[N], mex[N];
int fa[55];
void getSG(int n) {for(int i = 1; i <= n; i ++) {memset(mex, 0, sizeof(mex));for(int j = 1; fa[j] <= i; ++ j)mex[sg[i-fa[j]]] = 1;for(int j = 0; ; j ++) {if(!mex[j]) {sg[i] = j;break;}}}
}
int main() {int a, b, c;fa[1] = 1, fa[2] = 2;for(int i = 3; i < 55; i ++) fa[i] = fa[i-1] + fa[i-2];getSG(1000);while(cin >> a >> b >> c) {if(a==0 && b==0 && c==0)break;if(sg[a] ^ sg[b] ^ sg[c])printf("Fibo\n");else printf("Nacci\n");}return 0;
}

View Code

#include <bits/stdc++.h>
using namespace std;const int  M = 105;
int sg[M][M], vis[M], n, m;void fun()
{memset(sg, 0, sizeof(sg));for (int i = 1; i <= m; i++)for (int j = 1; j <= m; j++){if (i == j) continue;memset(vis, 0, sizeof(vis));if (i < j) {for (int k = i + 1; k < j; k++)vis[ sg[k][j] ] = 1, vis[ sg[i][k] ] = 1;}else if (i > j) {for (int k = j + 1; k < i; k++ )vis[ sg[k][j] ] = 1, vis[ sg[i][k] ] = 1;}for (int k = 0;; k++)if (!vis[k])  { sg[i][j] = k; break; }}
}int main()
{int a, b;while (cin >> n >> m){int ans = 0;fun();while (n--) {scanf("%d%d", &a, &b);ans ^= sg[a][b];}if (ans == 0) cout << "BAD LUCK!" << endl;else cout << "I WIN!" << endl;}
}

View 同上 一道题 Code

hdu1730  hdu1848  hdu1536 hdu2873

http://acm.hdu.edu.cn/showproblem.php?pid=1907

转载于:https://www.cnblogs.com/163467wyj/p/9399105.html

初学 博弈论 又称对策论 Game Theory相关推荐

  1. 博弈论又称对策论的入门及在军事博弈问题上的简单实战

      学习知识要实时简单回顾,我把学习的博弈论简单梳理一下,方便入门与复习. 博弈论模型 博弈论简介   社会及经济的发展带来了人与人之间或团体之间的竞争及矛盾,应用科学的方法来解决这样的问题开始于 1 ...

  2. 博弈论 —— python

    目录 1.简介 2.算法原理 3.实例分析 1.各参数初始化 2.计算期望与实际期望 3.博弈过程 4.绘图 完整代码 1.简介         博弈论又被称为对策论(Game Theory)既是现代 ...

  3. 博弈论 —— matlab

    目录 1.简介 2.算法原理 3.实例分析 1.各参数初始化 2.计算期望与实际期望 3.博弈过程 4.绘图 完整代码 1.简介         博弈论又被称为对策论(Game Theory)既是现代 ...

  4. 区块链之旅(四)双花攻击、博弈论、Hash函数、数字签名

    双花攻击 简介 "双花",即一笔钱被花了两次或者两次以上,也叫"双重支付" "双花攻击",又叫"双重消费攻击",即同一笔 ...

  5. 100种思维模型之那什均衡思维模型-038

    相信很多人都看过<美丽心灵>这部经典影片.这部影片的主人公就是诺贝尔经济学奖获得者约翰 · 纳什. 几个年轻的学者在酒吧找乐子,百无聊赖之际,一绝世美女突然降临,身边还有4位女性伙伴.学者 ...

  6. 奠定了整个计算机科学的基础是什么,冯 诺依曼对计算机科学发展所作的贡献是什么...

    冯 诺依曼对计算机科学发展所作的贡献是:C.提出存储程序工作原理,并设计出第一台具有存储程序功能的计算机EDVAC. 冯·诺伊曼对世界上第一台电子计算机ENIAC(电子数字积分计算机)的设计提出过建议 ...

  7. 电子计算机之父冯.诺依曼的主要贡献,冯•诺依曼的贡献有哪些?

    冯•诺伊曼还是20世纪最重要的数学家之一,在纯粹数学和应用数学方面都有杰出的贡献.他的工作大致可以分为两个时期. 1940年以前,主要是纯粹数学的研究:在数理逻辑方面提出简单而明确的序数理论,并对集合 ...

  8. [今日名人回顾]计算机之父—冯·诺依曼

    冯·诺伊曼,著名美籍匈牙利数学家.1903年12月3日生于匈牙利布达佩斯的一个犹太人家庭 冯·诺依曼的父亲麦克斯年轻有为.风度翩翩,凭着勤奋.机智和善于经营,年轻时就已跻身于布达佩斯的银行家行列.冯· ...

  9. java 生成图片验证码结合struts2使用

    验证码生成器类 package com.itest.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphic ...

最新文章

  1. Ubuntu18.04 ROS Melodic安装全过程整理
  2. 4G EPS 中的消息类型
  3. Excel 2013中单元格添加下拉列表的方法
  4. AjaxToolKit学习笔记 之 ModalPopupExtender
  5. 11-散列3 QQ帐户的申请与登陆 (25 分)
  6. AirtestIDE 教程 — 5分钟上手自动化测试
  7. 最高201万!华为高薪招应届生!专业是...
  8. setstate是同步还是异步_谈谈 IO模型:同步、异步、阻塞、非阻塞
  9. 你读过的最心酸的句子有哪些?
  10. Java异常统一处理
  11. 免费python网络课程-2019年10种免费的Python学习课程
  12. 计算机考试宏的录制,最新版本:鼠标和键盘录制工具(宏录制器)
  13. 多媒体技术计算机系统由组成,多媒体技术概述及多媒体计算机系统的组成
  14. 如何在Android设备上识别读取美国驾照信息
  15. cpu消耗 pytorch_PyTorch测试模型执行计算耗费的时间
  16. 关于WiFi和信号图标出现感叹号消除办法
  17. 北大计算机图灵班,北大首期“图灵班”开班
  18. 《以道御术》荣耀上市,高管书评
  19. 如何得到HP小型机的序列号
  20. wacom android 文件传输,专业原画师告诉你,wacom one到底值不值得买?

热门文章

  1. docker mysql 启动命令_Mac 下使用 Docker mysql 运行的容器如果挂载了/var/lib/mysql 不能启动容器...
  2. 如何在支付宝开直播,这篇入驻教程不要错过,看完你就会了
  3. 2017计科01-08编译原理模拟测试2--chap03
  4. vpc经典网络区别_阿里云经典网络与VPC网络互通的实现
  5. word办公插件中的佼佼者,Word魔方
  6. AURIX TriCore学习笔记四:LwIP裸机移植
  7. 从互联网进化的角度看AI+时代的巨头竞争
  8. 电子技术基础(三)__第1章 并联电路的电阻_电阻的分流公式
  9. 计算机本科毕业论文要求,计算机科学与技术学院本科毕业设计(论文)规范(试行)...
  10. OpenCV中稠密光流算法总结