sg函式用來求博弈過程中某一情況下是先手必敗(p-position)還是先手必勝(n-position)
性質:所有的先手必敗(p-position)當且僅當 sg = 0
所有的先手必勝(n-position)當且僅當 sg != 0
結束局面(t-position)sg = 0 ,可以理解為無法繼續操作了所以先手必敗
sg(x) = mex (mex是最小的不屬於該集合的非負整數,如mex = 2;
*若遊戲g是由g1,g2,g3..gk遊戲組合而成,相當於下一步將gi遊戲的狀態變成pi,即下一步的遊戲由g1,g2...gi-1,pi,gi+1,...gk-1,gk,此時sg(g) = sg(g1) ^ sg(g2) ^ sg(g3) ... sg(gk)
bzoj1188:
一篇寫的差不多的部落格:
先求出來每一a[i] ~ a[n]狀態下的sg
然後列舉i,j,k,相當於減去a[i]狀態下的遊戲,加上a[j],a[k]狀態下的遊戲
答案的sg就異或上a[i],a[j],a[k]
(感覺自己講的不是很清楚)
#include #include #include #define n 50
using namespace std;
int a[n],sg[n],f[n*n],n;
int main()
for (int j=0;j<=n*n;j++)
if (!f[j])
} //for (int i=1;i<=n;i++) printf("%d\n",sg[i]);
int tmp = 0;
for (int i=1;i<=n;i++) if (a[i] & 1) tmp ^= sg[i];
int tot = 0;
for (int i=1;i<=n;i++) if (a[i] != 0)
} if (!tot) printf("-1 -1 -1\n");
printf("%d\n",tot);
} return 0;
}
SG函式學習總結
有點散亂,將就著看吧.首先是博弈論的基礎,即 n 和 p 兩種狀態 n 為必勝狀態,p 為必敗狀態.對於n,p兩種狀態,則有 1.沒有任何合法操作的狀態,p 2.可以移動到p局面的情況為n狀態 3.可以移動到的所有狀態均為n狀態,則當前情況為p狀態.然後就可以引入sg函式了.首先定義mex運算,這是...
數學 nim博弈 SG函式
若乙個遊戲滿足 由兩名玩家交替行動 在遊戲程序的任意時刻,可以執行的合法行動與輪到哪名玩家無關 不能行動的玩家判負 則稱該遊戲為乙個公平組合遊戲。nim博弈屬於公平組合遊戲,但城建的棋類遊戲,比如圍棋,就不是公平組合遊戲。因為圍棋交戰雙方分別只能落黑子和白子,勝負判定也比較複雜,不滿足條件2和條件3...
模板 數學 博弈論 SG函式
f i 表示狀態i的後繼狀態,把它的後繼狀態push back 進去,然後呼叫getsg 就可以得到sg函式。無法轉移的狀態都是失敗狀態,這種寫法貌似只能向標號更小的狀態轉移 本身這個圖就是dag,就有拓撲序,所以本質上無所謂,更何況取石子非常直觀 所以一般f 0 就是失敗狀態。當然也可能會有別的失...