码迷,mamicode.com
首页 > 其他好文 > 详细

sg函数

时间:2016-08-07 15:19:39      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

       理解:sg函数,sg函数是博弈中表示当前状态的函数,具体的体现就是sg【】数组存的状态0为必败(或必胜看题意),非零即为相反的状态;

       因为是博弈,并采取最优策略,所以,当自己处于必胜态时,一定会把对手逼到必败态,对手无奈只能从给你必胜态,所以必胜态和必败态必然相连,只是先后手交替,才有了必

胜策略,sg数组很好的模拟了这一状态,虽然只是单次求解,但是,多次的只是异或关系,证明看

http://baike.baidu.com/link?url=JgEAj4YeawIVakrAvaPI1x6cOV242NCOqQ0javU1xlrQrckm58NpJLUf4VANMB6_HV5T6x7A2g290-a61bSAiq

       常用模版:

int sg[N];  
bool hash[N];  
void sg_solve(int *s,int t,int N)   //N求解范围 S[]数组是可以每次取的值,t是s的长度。  
{  
    int i,j;  
    memset(sg,0,sizeof(sg));  
    for(i=1;i<=N;i++)  
    {  
        memset(hash,0,sizeof(hash));  
        for(j=0;j<t;j++)  
            if(i - s[j] >= 0)  
                hash[sg[i-s[j]]] = 1;  
        for(j=0;j<=N;j++)  
            if(!hash[j])  
                break;  
        sg[i] = j;  
    }  
} 

       一个例题POJ2960 S-Nim

     

/*
*State: 1536    343MS    368K    1164 B    C++
*题目大意:
*        给定一个集合S,然后规定每一堆石头只能取集合S中
*        个数,然后要求出所有sg值,并判断结果。
*解题思路:
*        典型的求sg函数即可求解。
*题目困惑:
*        题目困惑了好久,最后我把错误排除到了求sg函数上,
*        可是还是觉得没有问题,最后还是看了别人的解题报告,
*        眼睛一扫,一秒就知道了问题所在。
*        其实我一开始就想到了S集合要排序,但是没有细想,就
*        过了,结果困扰了我这么久。
*
*        //忘记了排序,杯具了很久,排除了很多问题,最后觉得
*        //问题是出在求sg值上面了,结果排除问题也是对的,但是
*        //偏偏没有考虑到是f域里面要从小到大排序,因为求sg的
*        //时候,我的判断条件是
*        //while(i >= f[h] && h < n)
*        //    vst[sg[i - f[h++]]] = true;受这个影响,所以一定
*        //要排序。    
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <algorithm>
#include <map>
using namespace std;
#define sf scanf
#define pf printf
#define fuck cout<<"yes"<<endl;
#define mod 1e7+7
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MAXN = 10000;

int sg[MAXN];
bool ddddd[MAXN];
void sg_solve(int *s,int t,int N)   //N求解范围 S[]数组是可以每次取的值,t是s的长度。
{
    int i,j;
    memset(sg,0,sizeof(sg));
    for(i=1;i<=N;i++)
    {
        memset(ddddd,0,sizeof(ddddd));
        for(j=0;j<t;j++)
            if(i - s[j] >= 0)
                ddddd[sg[i-s[j]]] = 1;
        for(j=0;j<=N;j++)
            if(!ddddd[j])
                break;
        sg[i] = j;
    }
}

int s[MAXN];

int main()
{
 // freopen("1.in","r",stdin);
    int n;
    while(cin>>n&&n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>s[i];
        }
        sg_solve(s,n,MAXN);
        int m;
        cin>>m;
        for(int i=0;i<m;i++){
        int ans=0;
        int t;
        cin>>t;
        for(int j=0;j<t;j++)
        {
           int b;
           cin>>b;
            ans^=sg[b];
        }
        if(ans)cout<<"W";
            else cout<<"L";
        }cout<<endl;
    }

  return 0;
}

      模板中的hash有问题,提交编译出错,我的编译器bc查找替换快捷键为ALT+R;

sg函数

标签:

原文地址:http://www.cnblogs.com/aishuijdemiaomiao/p/5746047.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!