#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】博弈問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.