#include <iostream>
#include <cstdio>
#include <string.h>
#include <iomanip>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#define PI atan(1.0)*4
#define ture 1
#define false 0
/** 定义一个返回数组长度的 模板 **/
template<class T>
int length(T& data)
{
return sizeof(data)/sizeof(data[0]);
}
using namespace std;
/** 博弈问题 **/
/*
f(局面 x) ----> 胜负? (bool量)
边界条件的处理。。。 //剩下一个球 两个球 等等 的小的情况
for(对我所有可能的走法)
{
试着走一步 -----> 局面y ; //(局面x 发生了变化)
胜负 t = f(局面y) ; //(把局面y 交给对方走; 返回bool型的结果 是胜还是负)
if(t == 负)
return 胜;
恢复局面(有些情况下)
}
return 负;
*/
//局面 : n 所剩球的数目
int f(int n)
{
if(n >= 8 && f(n-8) == 0) return 1;
if(n >= 7 && f(n-7) == 0) return 1;
if(n >= 3 && f(n-3) == 0) return 1;
if(n >= 1 && f(n-1) == 0) return 1;
return 0;
}
string show_f(int n)
{
if(n == 0) return "负";
if(n == 1) return "胜";
}
int ff(int x[]) //x中存放每个小和尚的位置信息
{
for(int i = 0; i < length(x) - 1; i++)
{
for(int k = x[i] + 1; k < x[i+1]; k++)
{
int old = x[i];
x[i] = k;
try{
if(ff(x) == false) return ture;
}
catch(...)
{
}
x[i] = old; //回溯; 因为这个x[]是面向对象的指针 是全局的 全局都会改变
}
}
return false;
}
int main()
{
/*
盒子里有n个小球 a.b轮流取球
我们约定:
每个人从盒子中取出的球的数目必须是 1 ,3 , 7,或者8个.
4
l
2
10
18
则程序应该输出1
0
*/
/*
这个题目的局面很简单, 就是一个整数, 指的是剩下的球的数目
*/
cout << show_f(f(10)) << endl;
cout << show_f(f(1)) << endl;
cout << show_f(f(4)) << endl;
//cout << show_f(f(150)) << endl; //效率不高 。 应该用缓冲, 将已经计算过的局面保存。
//下一次计算只需要用哈希表即可
/** 井字棋 (有平局的博弈)**/
/*
棋盘类似于九宫格
画叉 画圈
胜负平
*/
/*
算法思路:
f(局面) -------> 胜负平
{
tag = 负;
for(对所有可走的位置进行进行搜索)
{
试走 ----> 局面y
结果 t = f(局面y);
if(t == 负) return 胜;
if(t == 平)tag = 平;
}
return tag;
}
*/
/**=================================**/
/*
现实的算法 :
不能计算到最终的胜负
。。。考量各种不同的局面 对不同的所有的局面进行打分 不能保证必胜 但是较优 不会出现低级失误
*/
/**=================================**/
/**高僧斗法**/
/*
核心代码:
ff()函数;
数学上研究的方法:
组合博弈论
尼姆公式(尼姆定理)
无偏的2人游戏, 都可以等价为一个, 尼姆堆
--------------------
无偏游戏: 不用区分棋盘上是谁的棋子 都可以动
--------------------
尼姆堆: 比如有3堆硬币 分别有 3 , 4 ,5 个硬币
可以从任何一堆 拿走 任意数目的硬币
(这个问题就是一个尼姆问题, 尼姆堆的数目为 3
--------------------
--------------------
不用递归的运算
一位数学家认为这里面实际上存在着 二进制的关系
--------------------
--------------------
3 | 1 1
4 | 1 0 0
5 | 1 0 1
--------------------
如果 列向上 1 的数目是偶数
那么 对方必输
--------------------
比如是 两堆完全相同的堆 那么列向一定是偶数 不管对方怎么取 都可以模仿对方进行取 所以必胜
--------------------
--------------------
算法思路:
高僧斗法 ----> 尼姆游戏
对于具体问题,通过一定的技巧转换成尼姆游戏
本题:
把小和尚间的空袭 看成是尼姆堆
小和尚数目:
偶数:两两组合
奇数:在最高阶补充一个假想的小和尚 然后两两组合
小组是可以跟随操作,不改变尼姆堆的值 a....b
*/
return 0;
}
【蓝桥杯学习记录】【8】博弈问题
最新推荐文章于 2018-05-20 15:21:40 发布