1. 程式人生 > >博弈sg函式

博弈sg函式

sg函式(個人認為還是用於三種方法都無法解決的情況,如按特殊數字取石子)

我們把整個博弈過程抽象為有向無環圖

1.      幾項準備工作:

mex求最小非負整數mex{} = 0,mex{0,1,2,4} = 3,mex{1,2,4} = 0

sg[x] =mex{sg[y]|y是x的後繼}//就是石頭變少的繼

這樣sg就滿足幾個性質

1.      sg[x] == 0時,它的後繼都不為零

2.      sg[x] != 0時,它的後繼一定有為零的

3.      當x點沒有出邊時,sg[x] == 0

這三個性質恰好與P-positon(先手必敗)的性質相同:

(1).無法進行任何移動的局面(也就是terminal position)是P-position;

(2).可以移動到P-position的局面是N-position;

(3).所有移動都導致N-position的局面是P-position。

由此可知:sg[x] == 0,x就是p-position

2.

         對於從一堆n個石塊中取石塊的過程,每次取法有一定特色(比如說按照菲薄納切數列來去)只需求出sg[x]就可以判斷了

         對於從m堆石塊中取石塊的過程,每次取法是特殊的。只需將所有s[n]亦或就是結果

讓我們再來考慮一下頂點的SG值的意義。當g(x)=k時,表明對於任意一個0<=i<k,都存在x的一個後繼y滿足g(y)=i。也就是說,當某枚棋子的SG

值是k時,我們可以把它變成0、變成1……、變成k-1但絕對不能保持k不變。不知道你能不能根據這個聯想到Nim遊戲,Nim遊戲的規則就是:每次選擇一堆數量為k的石子,可以把它變成0、變成1、……、變成k-1,但絕對不能保持k不變。這表明,如果將n枚棋子所在的頂點的SG值看作n堆相應數量的石子,那麼這個Nim遊戲的每個必勝策略都對應於原來這n枚棋子的必勝策略!

假設一堆石塊有n個石塊這就意味著sg[n]確實等價為從n個石塊中每次至少取一個石頭

4.模板.注意要根據題目的要求初始化a[i]。切記初始化sg都為-1,init中的a一定是從小到大的

實踐證明暴搜比打錶快。因為暴搜得到的值,不用也不應該清空。下一次可以根據上一次暴搜得到的值進行處理

         1.dfs遞迴版。從n個石頭開始遞迴

呼叫方式:SG(n)

<pre name="code" class="cpp">const int MAXN=1005;

int a[MAXN],sg[MAXN];


void init()
{
    a[1] = 1,a[2] = 2;
    for(int i = 3; i < 20; i ++)
    {
        a[i] = a[i - 1] + a[i - 2];
        // cout<<a[i]<<endl;
    }
 }

int SG(int x)
{
    bool vis[105] = {false};
    int temp;
    for(int i = 0; i <n && a[i]<= x; i ++)//n是i的個數
    {
        temp= x - a[i];
        if(sg[temp]== -1)
        {
            sg[temp] = SG(temp);
        }
        vis[sg[temp]]= true;
    }
    for(int i = 0;; i ++)
    {
        if(vis[i]== false)
        {
            return i;
        }
    }
}


2.      打表法

呼叫方法:sg[n]

const int MAXN=1005;

int a[MAXN],sg[MAXN],b[MAXN];
int n,maxx;//maxx表示sg[]表的大小。n表示的是a[]的大小,也就是每一步所能走的值的集合的大小
void init()
{
    a[1] = 1,a[2] = 2;
    for(int i = 3; i < 20; i ++)
    {
        a[i] = a[i - 1] + a[i - 2];
        // cout<<a[i]<<endl;
    }
 }

void SG()
{
    for(int i = 0; i <= maxx; i ++)
    {
        memset(b,true,sizeof(b));
        for(int j = 0; j < n; j ++)
        {
            if(i < a[j])
                break;
            b[sg[i - a[j]]] = false;//不是i - a[j]是sg[i-a[j]]

        }
        for(int j = 0; j <= maxx; j ++)

        {
            if(b[j])
            {
                sg[i] = j;
                break;
            }
        }
    }
}

相關推薦

hdu 1848 博弈sg函式打表

這道題是典型的sg函式來解決的博弈問題。 先給出了可以移動石子數量的取值區間就是一個一千以下的斐波那契數列,這個好辦,直接一個數組完事。 然後給出三堆石子的數量,m,n,p; 我們的思路就是把1000以下的所有數的sg值都打表出來。 然後再將m n p三個數的sg值異

博弈論知識點總結(巴什博奕 威佐夫博弈 尼姆博弈 SG()函式介紹)

總結 真心感謝博主,終於知道為什麼尼姆博弈用異或來解決。 SG函式模板: void init()//根據題目要求進行修改 { a[0]=1; for(int i=1;i<=32;i

博弈sg函式

sg函式(個人認為還是用於三種方法都無法解決的情況,如按特殊數字取石子) 我們把整個博弈過程抽象為有向無環圖 1.      幾項準備工作: mex求最小非負整數mex{} = 0,mex{0,1,2

博弈——sg函式sg定理

在介紹SG函式和SG定理之前我們先介紹介紹必勝點與必敗點吧. 必勝點和必敗點的概念:        P點:必敗點,換而言之,就是誰處於此位置,則在雙方操作正確的情況下必敗。        N點:必勝點,處於此情況下,雙方操作均正確的情況下必勝。 必勝點和必敗點的性質

三大經典博弈 尼姆博奕 + 巴仕博弈 + 威佐夫博弈 +SG函式

第一,尼姆博奕(Nimm Game) 一,特例分析 有三堆各若干個物品,兩個人輪流從某一堆取任意多的 物品,規定每次至少取一個,多者不限,最後取光者得勝。 我們用(a,b,c)表示某種局勢,首先(0,

筆記——博弈 SG函式

博弈問題博大精深啊 。。。sg函式 原理證明不做贅述,直接子額怎麼用首先你必須知道P點與N點簡單來說P點 ——誰從這個點走誰就輸        N點——誰從這個點走誰就贏這兩個有大大的關係  只要從必敗點(P點)走必然下一步就會走到必勝點 (N點)反之類比一下 只要從必勝點

博弈SG函式

遇到博弈的一些題目不能直接找規律,但是一些問題是有類似於分治的思想,就是大問題能轉為更小的子問題,如:100個石頭拿5個走,那問題就簡化為95個石頭。 SG即用一個有向圖表示輸贏狀態,圖中的結點值為0表示先手必敗,非0為先手必勝點,即: 對於一個局面x,它的sg值: (1

LightOJ 1315【Nim博弈】 二維SG函式與記憶化搜尋

A Hyper Knight is like a chess knight except it has some special moves that a regular knight cannot do. Alice and Bob are playing this game (you may w

hdu-1404 (博弈 篩法 sg函式

題目大意:一個至多6位正整數(可以有前導0),a和b兩個人輪流進行操作,有兩種操作方法: 1.將這個數的任意一位轉換為比這一位小的數 2.假如這個數字存在0,可以刪除0並且這個0之後的所有的數 誰最後一個進行操作,下一個人無法操作了,這個人勝。 分析: 1.

Light OJ-1344 Aladdin and the Game of Bracelets DP(記憶化搜尋) + SG函式 博弈

題目描述 It’s said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a powerful Genie. Here we

SG函式淺談解決博弈問題的通法

                          從SG函式淺談解決博弈問題的通法   轉載:https://www.cnblogs.com

SG函式博弈函式

必勝點和必敗點的概念:        P點:必敗點,換而言之,就是誰處於此位置,則在雙方操作正確的情況下必敗。        N點:必勝點,處於此情況下,雙方操作均正確的情況下必勝。 必勝點和必敗點的性質:         1、所有終結點是 必敗點 P 。(我們以此為基本

博弈問題及SG函式(真的很經典)

博弈問題 若你想仔細學習博弈論,我強烈推薦加利福尼亞大學的Thomas S. Ferguson教授精心撰寫並免費提供的這份教材,它使我受益太多。(如果你的英文水平不足以閱讀它,我只能說,恐怕你還沒到需要看“博弈論”的時候。) Nim遊戲是博弈論中最經典的模型(之一?),它又有

博弈論 | 詳解搞定組合博弈問題的SG函式

本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天這篇是演算法與資料結構專題的第27篇文章,我們繼續深入博弈論問題。今天我們要介紹博弈論當中非常重要的一個定理和函式,通過它我們可以解決許多看起來雜亂無章的博弈問題,使得我們可以輕鬆地解決一大類博弈問題。 有了SG函式和SG定理,我們

博弈sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree

paths 相同 friend pri 產生 chan star ren have Sagheer is playing a game with his best friend Soliman. He brought a tree with n nodes numbered

HDU 1848 Fibonacci again and again(簡單博弈SG函數)

sg函數 pro htm break www amp 函數 true .cn 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1848 題目: 1、 這是一個二人遊戲;2、 一共有3堆石子,數量分別是m, n, p個;3、

bzoj1022: [SHOI2008]小約翰的遊戲John(博弈SG-nim遊戲)

mat flag enter int ans problem blank 入門題 pos 1022: [SHOI2008]小約翰的遊戲John 題目:傳送門 題目大意:    一道反nim遊戲,即給出n堆石子,每次可以取完任意一堆或一堆中的若幹個(至少取1),最後一

hdu-3980-nim博弈/sg函數

rst sub tin bre sim others tput sea names Paint Chain Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

hdu 5724 Chess (SG函式

題目連結:hdu 5724 題意:有一個n行20列的棋盤,棋盤上分佈著一些棋子,A、B兩人輪流下棋,A先手,每次操作可以將某個棋子放到自己右邊的第一個空位(也就是說右邊如果已經有子,可以跳過它,沒有就右移一步),但最多20列,絕對不能超過棋盤,無棋可走的輸。 題解:進行狀態壓縮,bit來

SG函式入門

參考部落格:https://baike.baidu.com/item/SG%E5%87%BD%E6%95%B0/1004609 https://www.cnblogs.com/ECJTUACM-873284962/p/6921829.html 主要參考百度百科: 首先定義mex(mi