博弈論 sg函數

http://baike.baidu.com/link?url=RvHq88XaFKNd0XJC97k2JWvIJSPZiLKvVhVnA_yCPR_K-cZhb2lLIjG3XHatW8VeyzLxbbOvYWqEtcc2RSdls_7mPQDbixegyJFRIBJFdj_

http://www.cnblogs.com/frog112111/p/3199073.html

兩人操控一個棋子要從起點到終點,每次可以走若干步(看下邊的三種規則),誰無路可走誰就輸。

對於一個子遊戲(之所以說是子游戲,是因爲情況可能不止一個棋子,比如兩人操作兩個棋子。可以認爲一個棋子是一個子遊戲。而總遊戲的勝利爲各個子游戲的sg的異或)(sg[i]爲0爲必敗點,不爲0爲必勝點)

三種規則

1.每次可以走任意步,那麼sg[i] = i,

2.每次可以走1~m步,那麼sg[i] = i%(m+1),

3對於不連續的步數。下面的函數。

#include<vector>
#include<iostream>

using namespace std;

vector<int> sg(20);
vector<int> f = {0,1,2,5};//每次可以走的步數,這裏設爲1,2,,5。f[0]無意義。
std::vector<int> hash0(20);//找到mex({sg[當前步數減去可以走的步數}),最小非負整數

void getsg(int n)
{
	for(int i=0; i<sg.size(); i++) sg[i] = 0;
	for(int i=1; i<=n; i++)
	{
		for(int i=0; i<hash0.size(); i++) hash0[i] = 0;
		for(int j=1; f[j] <= i; j++)
		{
			hash0[sg[i-f[j]]] = 1;
		}
		for(int j=0; j <=n; j++)
		{
			if(hash0[j] == 0)
			{
				sg[i] = j;
				break;
			}
		}
		cout<<i<<"  "<<sg[i]<<endl;
	}
 }
 
 int main()
 {
 	getsg(20);
 	return 0;
  } 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章