博弈的題大多數用sg函式打表找規律
博弈的題大多數用sg函式打表找規律
博弈的題大多數用sg函式打表找規律
記憶話搜尋可以更快
記憶話搜尋可以更快
記憶話搜尋可以更快
定義sg值為0時表示後手必勝,sg為1時為先手必勝。
那麼對於每乙個人,都會去查詢使得當前狀態變成sg值為0的情況
那麼就是說,對於多種情況,只會選擇sg值最小的情況進行選擇,遍歷一下,看看以我為起點進行,最終到達的情況是如果是sg值為0,那麼我就進行選擇,否則只能任意選擇
第一種打表寫法。
從現狀態開始進行查詢。
對於必敗方的情況都返回0,此時的必敗狀態就是一眼能看出來的情況,即不用博弈就知道先手必勝的情況。
然後令sg值為1,表示我必輸狀態,再取判斷所有情況,得到所有情況的sg值,取最小值
第二種打表寫法
從先手必敗的局勢開始往後遞推
2020ccpc綿陽的g題
有0123這4種數字a,b,c,d張,每次可以拿走兩個數字,和≤3,然後用兩個數字的和來代替,放回數字堆。兩個人進行博弈
sg函式打表
int sg(int a, int b, int c, int d)
然後直接打表得到規律。
#include #include using namespace std;
int sg(int a, int b, int c, int d)
bool check(int a, int b, int c, int d)
if(a & 1) else
return 1;
}int main()
return 0;
}
傳送門
直接sg打表就行了,必敗情況是n = 1時
因為考慮到答案是求≥n時結束,也相當於是除以某個數字向上取整的意思
記憶話搜尋一下防止超時
#include #include #include #define ll long long
using namespace std;
const int n = 1e5 + 4;
std::mapmp;
bool sg(ll n)
return mp[n] = 1 - f;
}int main()
return 0;
}
傳送門
這個可以用第二種打表方法進行
從先手必敗的(0,0,0)進行遞推
#include #include using namespace std;
const int n = 305;
bool sg[n][n][n];
void init()}}
}}int main()
return 0;
}
我對SG函式的理解
i 的sg函式g i 定義如下 如果該點沒有出邊,g i 0 否則定義乙個mex minimal excludant 操作,這是對乙個集合進行的操作,返回值為集合中所不包含的最小的非負整數,那麼g i m ex。顯然對於乙個有向無環圖,我們都能在o 狀態總數 每個點 的後繼狀 態數 時間內求出所有點...
自己對sg函式的小理解
首先定義mex minimal excludant 運算,這是施加於乙個集合的運算,表示最小的不屬於這個集合的非負整數。例如mex 3 mex 0 mex 0。對於乙個給定的有向無環圖,定義關於圖的每個頂點的sprague garundy函式g如下 g x mex。sg函式的一些性質 1 當sg 0...
邂逅明下 博弈 SG打表找規律)
當日遇到月,於是有了明。當我遇到了你,便成了侶。那天,日月相會,我見到了你。而且,大地失去了光輝,你我是否成侶?這注定是個淒美的故事。以上是廢話 小t和所有世俗的人們一樣,期待那百年難遇的日食。駐足街頭看天,看日月漸漸走近,小t的脖子那個酸呀 他堅持這個姿勢已經有半個多小時啦 他低下仰起的頭,環顧四...