博弈論(2)

上篇博客簡單的介紹了一些經典的博弈,這篇繼續寫一些博弈問題。移動棋子游戲
移動棋子游戲
這個是一個應用SG函數的板子題.

#include <bits/stdc++.h>
using namespace std;
const int N=2010,M=6010;
int n,m,k,a,b,x;
vector<int> ve[N];
int sg[N];
int SG(int u)
{
    if(sg[u]!=-1)
        return sg[u];
    set<int> st;
    for(int i=0;i<ve[u].size();i++)
    {
        int j=ve[u][i];
        st.insert(SG(j));
    }
    for(int i=0;;i++)
    {
        if(!st.count(i))
        {
            sg[u]=i;
            break;
        }
    }
    return sg[u];
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
    {
        cin>>a>>b;
        ve[a].push_back(b);
    }
    memset(sg,-1,sizeof sg);
    int res=0;;
    for(int i=0;i<k;i++)
    {
        cin>>x;
        res ^= SG(x);
    }
    if(res)
        cout<<"win"<<endl;
    else
        cout<<"lose"<<endl;
    return 0;
}

再補充一下SG函數,SG 函數就是按照阿拉伯數字順序不在某集合中的最小數。在這裏插入圖片描述
就像上圖,節點5不能到任何點,所以他的sg[5]爲0。
因爲節點4只能到節點5,而且節點4所到點的集合{0},不在集合的最小自然數爲1,所以sg[4]=1.
節點3到能到節點4和5,所以節點3的集合爲{0,1},不在集合的最小自然數爲2,所以sg[3]=2,剩下的以此類推。
重點就是sg函數的想法,至於求法,鏈表鄰接表什麼的都行,上面我用的vector求的。

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