sg函数入门理解
首先理解sg函數必須先理解mex函數
mex是求除它集合內的最小大于等于0的整數,例:mex{1,2}=0;mex{2}=0;mex{0,1,2}=3;mex{0,5}=1。
而sg函數是啥呢?
對于任意狀態 x , 定義 sg(x) = mex(f),其中f 是 x 后繼狀態的sg函數值的集合(就是上述mex中的數值)。最后返回值(也就是sg(x))為0為必敗點,不為零必勝點。
看不懂,咱直接來個例子:
例如:取石子問題,有1堆n個的石子,每次只能取{1,3,4}個石子,先取完石子者勝利,那么各個數的SG值為多少?
sg[0]=0,f[]={1,3,4},
?
x=1時,可以取走1-f{1}個石子,剩余{0}個,mex{sg[0]}={0},故sg[1]=1;
x=2時,可以取走2-f{1}個石子,剩余{1}個,mex{sg[1]}={1},故sg[2]=0;
x=3時,可以取走3-f{1,3}個石子,剩余{2,0}個,mex{sg[2],sg[0]}={0,0},故sg[3]=1;
x=4時,可以取走4-f{1,3,4}個石子,剩余{3,1,0}個,mex{sg[3],sg[1],sg[0]}={1,1,0},故sg[4]=2;
x=5時,可以取走5-f{1,3,4}個石子,剩余{4,2,1}個,mex{sg[4],sg[2],sg[1]}={2,0,1},故sg[5]=3;
以此類推.....
? ?x ? ? ? ? 0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8....
sg[x] ? ? ?0 ?1 ?0 ?1 ?2 ?3 ?2 ?0 ?1...
計算從1-n范圍內的SG值。
f(存儲可以走的步數,f[0]表示可以有多少種走法)
這下就ojbk了吧
f[]需要從小到大排序
1.可選步數為1~m的連續整數,直接取模即可,SG(x) = x % (m+1);
2.可選步數為任意步,SG(x)?= x;
3.可選步數為一系列不連續的數,用GetSG()計算
再附個模板吧
1 //f[]:可以取走的石子個數 2 //sg[]:0~n的SG函數值 3 int f[maxn],sg[maxn],mex[maxn]; 4 void getSG(int n){ 5 int i,j; 6 memset(sg,0,sizeof(sg)); 7 for(i=1;i<=n;i++){ 8 memset(mex,0,sizeof(mex)); 9 for(j=1;f[j]<=i&&f[j]<=m;j++) //注意加f[i]的限定條件,此處為f[j]<=m 10 mex[sg[i-f[j]]]=1; 11 for(j=0;j<=n;j++){ //求mex中未出現的最小的非負整數 12 if(mex[j]==0){ 13 sg[i]=j; 14 break; 15 } 16 } 17 //cout<<i<<" "<<sg[i]<<endl; 18 } 19 }?
轉載于:https://www.cnblogs.com/warmingtxdy/p/11320455.html
總結
- 上一篇: 运放的典型电路举例与计算仿真
- 下一篇: 三极管基本参数介绍与放大电路分析