日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

博弈-sg函数的原理和优化(hdu-1536)

發布時間:2023/12/2 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 博弈-sg函数的原理和优化(hdu-1536) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
sg函數:sg函數是博弈中的確定一個position性質的一個函數,全稱是sprague-grundy。

性質1:對于所有的p-position,都有sg = 0;對于所有的n-position都有sg != 0;

性質2:某點a的sg函數的值由它的后繼的sg函數的值來決定,設后繼為b, c, d, e……則sg(a) = mex(sg(a), sg(b), sg(c), sg(d), sg(e),……)

mex是不屬于這個集合的最小非負整數。

應用范圍:在此無環圖中誰無法再次移動,便是輸。(如果誰無法移動,便是贏,暫時不知如何解決。)

應用:通過判斷該點,sg = 0是p點,sg != 0是N點。

構造sg函數的方法:

方法一:打表

例題:hdu-1536-S-nim?點擊打開鏈接


[cpp] view plaincopyprint?
  • /*?
  • 收獲:?
  • */??
  • #include<iostream> ??
  • #include<cstdlib> ??
  • #include<vector> ??
  • #include<map> ??
  • #include<cstring> ??
  • #include<set> ??
  • #include<string> ??
  • #include<algorithm> ??
  • #include<sstream> ??
  • #include<ctype.h> ??
  • #include<fstream> ??
  • #include<string.h> ??
  • #include<stdio.h> ??
  • #include<math.h> ??
  • #include<stack> ??
  • #include<queue> ??
  • #include<ctime> ??
  • //#include<conio.h> ??
  • using?namespace?std;??
  • ??
  • const?int?INF_MAX=0x7FFFFFFF;??
  • const?int?INF_MIN=-(1<<31);??
  • ??
  • const?double?eps=1e-10;??
  • const?double?pi=acos(-1.0);??
  • ??
  • #define?pb?push_back???//a.pb(?) ??
  • #define?chmin(a,b)?((a)<(b)?(a):(b)) ??
  • #define?chmax(a,b)?((a)>(b)?(a):(b)) ??
  • ??
  • ??
  • template<class?T>?inline?T?gcd(T?a,T?b)//NOTES:gcd( ??
  • ??{if(a<0)return?gcd(-a,b);if(b<0)return?gcd(a,-b);return?(b==0)?a:gcd(b,a%b);}??
  • template<class?T>?inline?T?lcm(T?a,T?b)//NOTES:lcm( ??
  • ??{if(a<0)return?lcm(-a,b);if(b<0)return?lcm(a,-b);return?a*(b/gcd(a,b));}??
  • ??
  • ??
  • typedef?pair<int,?int>?PII;??
  • typedef?vector<PII>?VPII;??
  • typedef?vector<int>?VI;??
  • typedef?vector<VI>?VVI;??
  • typedef?long?long?LL;??
  • int?dir_4[4][2]={{0,1},{-1,0},{0,-1},{1,0}};??
  • int?dir_8[8][2]={{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}};??
  • //下,左下,左,左上,上,右上,右,右下。 ??
  • ??
  • //*******?WATER?**************************************************************** ??
  • ??
  • ??
  • const?int?MAXN?=?10500;??
  • bool?judge[150];??
  • int?sg[MAXN];??
  • int?M[150];??
  • const?int?Init?=?1e7;??
  • int?Num;??
  • ??
  • void?input_m()??
  • {??
  • ????for(int?i?=?0;?i?<?Num;?i++)??
  • ????{??
  • ????????cin>>M[i];??
  • ????}??
  • ????return?;??
  • }??
  • ??
  • void?debug()??
  • {??
  • ????cout<<"sg?function"<<endl;??
  • ????for(int?i?=?0;?i?<?100;?i++)??
  • ????{??
  • ????????cout<<i<<"?"<<sg[i]<<endl;??
  • ????}??
  • ????return?;??
  • }??
  • ??
  • void?getsg()??
  • {??
  • ????for(int?i?=?0;?i?<?MAXN;?i++)??
  • ????{??
  • ????????memset(judge,?false,?sizeof(judge));??
  • ????????//int?tsg?=?Init; ??
  • ????????for(int?j?=?0;?j?<?Num;?j++)??
  • ????????{??
  • ????????????int?ps?=?i?-?M[j];??
  • ????????????if(ps?>=?0)?judge[sg[ps]]?=?true;??
  • ????????}??
  • ????????//if(tsg?==?Init)?tsg?=?0; ??
  • ????????for(int?j?=?0;?j?<?Num?+?1;?j++)??
  • ????????{??
  • ????????????if(judge[j]?==?false)??
  • ????????????{??
  • ????????????????sg[i]?=?j;??
  • ????????????????break;??
  • ????????????}??
  • ????????}??
  • ????}??
  • ????//debug(); ??
  • ????return?;??
  • }??
  • int?main()??
  • {??
  • ????//freopen("input.txt","r",stdin); ??
  • ????//freopen("output.txt","w",stdout); ??
  • ????while(cin>>Num,?Num)??
  • ????{??
  • ????????input_m();??
  • ????????getsg();??
  • ????????int?num;??
  • ????????cin>>num;??
  • ????????while(num--)??
  • ????????{??
  • ????????????int?nn,?tp;??
  • ????????????cin>>nn;??
  • ????????????int?ret?=?0;??
  • ????????????for(int?i?=?0;?i?<?nn;?i++)??
  • ????????????{??
  • ????????????????cin>>tp;??
  • ????????????????ret?^=?sg[tp];??
  • ????????????}??
  • ????????????if(ret?==?0)?cout<<"L";??
  • ????????????else?cout<<"W";??
  • ????????}??
  • ????????cout<<endl;??
  • ????}??
  • ????return?0;??
  • ????//printf("%.6f\n",(double)clock()/CLOCKS_PER_SEC); ??
  • }??
  • /* 收獲: */ #include<iostream> #include<cstdlib> #include<vector> #include<map> #include<cstring> #include<set> #include<string> #include<algorithm> #include<sstream> #include<ctype.h> #include<fstream> #include<string.h> #include<stdio.h> #include<math.h> #include<stack> #include<queue> #include<ctime> //#include<conio.h> using namespace std;const int INF_MAX=0x7FFFFFFF; const int INF_MIN=-(1<<31);const double eps=1e-10; const double pi=acos(-1.0);#define pb push_back //a.pb( ) #define chmin(a,b) ((a)<(b)?(a):(b)) #define chmax(a,b) ((a)>(b)?(a):(b))template<class T> inline T gcd(T a,T b)//NOTES:gcd({if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);} template<class T> inline T lcm(T a,T b)//NOTES:lcm({if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}typedef pair<int, int> PII; typedef vector<PII> VPII; typedef vector<int> VI; typedef vector<VI> VVI; typedef long long LL; int dir_4[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; int dir_8[8][2]={{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1}}; //下,左下,左,左上,上,右上,右,右下。//******* WATER ****************************************************************const int MAXN = 10500; bool judge[150]; int sg[MAXN]; int M[150]; const int Init = 1e7; int Num;void input_m() {for(int i = 0; i < Num; i++){cin>>M[i];}return ; }void debug() {cout<<"sg function"<<endl;for(int i = 0; i < 100; i++){cout<<i<<" "<<sg[i]<<endl;}return ; }void getsg() {for(int i = 0; i < MAXN; i++){memset(judge, false, sizeof(judge));//int tsg = Init;for(int j = 0; j < Num; j++){int ps = i - M[j];if(ps >= 0) judge[sg[ps]] = true;}//if(tsg == Init) tsg = 0;for(int j = 0; j < Num + 1; j++){if(judge[j] == false){sg[i] = j;break;}}}//debug();return ; } int main() {//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);while(cin>>Num, Num){input_m();getsg();int num;cin>>num;while(num--){int nn, tp;cin>>nn;int ret = 0;for(int i = 0; i < nn; i++){cin>>tp;ret ^= sg[tp];}if(ret == 0) cout<<"L";else cout<<"W";}cout<<endl;}return 0;//printf("%.6f\n",(double)clock()/CLOCKS_PER_SEC); }

    方法二:遞歸迭代

    以下

    [cpp] view plaincopyprint?
  • #include"iostream" ??
  • #include"algorithm" ??
  • #include"string.h" ??
  • using?namespace?std;??
  • int?s[101],sg[10001],k;??
  • int?getsg(int?m)??
  • {??
  • ????int?hash[101]={0};??
  • ????int?i;??
  • ????for(i=0;i<k;i++){??
  • ????????if(m-s[i]<0)??
  • ????????????break;??
  • ????????if(sg[m-s[i]]==-1)??
  • ????????????sg[m-s[i]]=getsg(m-s[i]);??
  • ????????hash[sg[m-s[i]]]=1;??
  • ????}??
  • ????for(i=0;;i++)??
  • ????????if(hash[i]==0)??
  • ????????????return?i;??
  • ???
  • ???
  • }??
  • int?main()??
  • {??
  • ????//int?k; ??
  • ???//?freopen("game.in","r",stdin); ??
  • ????//freopen("game.out","w",stdout); ??
  • ????while(cin>>k,k)??
  • ????{??
  • ????????int?i;??
  • ????????for(i=0;i<k;i++)??
  • ????????????cin>>s[i];??
  • ????????sort(s,s+k);??
  • ????????memset(sg,-1,sizeof(sg));??
  • ????????sg[0]=0;??
  • ????????int?t;??
  • ????????cin>>t;??????
  • ????????while(t--)??
  • ????????{??
  • ???????????????
  • ????????????int?n,m;??
  • ????????????cin>>n;??
  • ????????????int?ans=0;??
  • ????????????while(n--)??
  • ????????????{??
  • ????????????????cin>>m;??
  • ????????????????if(sg[m]==-1)??
  • ????????????????????sg[m]=getsg(m);??
  • ????????????????ans^=sg[m];??
  • ????????????}??
  • ????????????if(ans)??
  • ????????????????cout<<'W';??
  • ????????????else?cout<<'L';??
  • ????????}??
  • ????????cout<<endl;??
  • ????}??
  • ????return?0;??
  • }??
  • #include"iostream" #include"algorithm" #include"string.h" using namespace std; int s[101],sg[10001],k; int getsg(int m) {int hash[101]={0};int i;for(i=0;i<k;i++){if(m-s[i]<0)break;if(sg[m-s[i]]==-1)sg[m-s[i]]=getsg(m-s[i]);hash[sg[m-s[i]]]=1;}for(i=0;;i++)if(hash[i]==0)return i;} int main() {//int k;// freopen("game.in","r",stdin);//freopen("game.out","w",stdout);while(cin>>k,k){int i;for(i=0;i<k;i++)cin>>s[i];sort(s,s+k);memset(sg,-1,sizeof(sg));sg[0]=0;int t;cin>>t; while(t--){int n,m;cin>>n;int ans=0;while(n--){cin>>m;if(sg[m]==-1)sg[m]=getsg(m);ans^=sg[m];}if(ans)cout<<'W';else cout<<'L';}cout<<endl;}return 0; }
    是別人的代碼:

    總結

    以上是生活随笔為你收集整理的博弈-sg函数的原理和优化(hdu-1536)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。