博弈论合集

hdu 1847

#include 
#include 
#include 
#include 
using namespace std;
int dp[1003];
int main()
{
    int p[30];
    p[0]=1;
    for(int i=1;i<20;i++){
        p[i]=p[i-1]<<1;
    }
    memset(dp,0,sizeof(dp));
    dp[0]=0;dp[1]=1;
    dp[2]=1;
    for(int i=3;i<1003;i++){
        for(int j=0;j<20;j++){
            if(p[j]<=i){
                if(dp[i-p[j]]==0)dp[i]=1;
            }
        }
    }
    int n;
    while(scanf("%d",&n)!=EOF){
        dp[n]==0?printf("Cici\n"):printf("Kiki\n");
    }

    return 0;
}

hdu 1848


#include 
#include 
#include 
#include 
#include 
using namespace std;
int sg[1045];
int f[100];

void grundy(){
    sg[0]=0;
    for(int j=1;j<=1000;j++){
        sets;
        for(int i=1;i<20;i++){
            if(f[i]<=j)s.insert(sg[j-f[i]]);
        }
        int g=0;
        while(s.count(g))g++;
        sg[j]=g;
    }
}

int main()
{
    f[0]=1;
    f[1]=1;
    f[2]=2;
    for(int i=3;i<20;i++){
        f[i]=f[i-1]+f[i-2];
    }
    grundy();
    int n,m,p;
    while(~scanf("%d%d%d",&n,&m,&p)){
        if(!n&&!m&&!p)break;
        string ans=(sg[n]^sg[m]^sg[p])==0?"Nacci":"Fibo";
        cout<

hdu 5724

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

int sg[1100000];
int s[30];
void grundy(){
    sg[0]=0;
    for(int i=1;i<(1<<20);i++){
        memset(s,0,sizeof(s));
        for(int j=0;j<20;j++){
            if(i&(1<=0;k--){
                    if(!(i&(1<

hdu 1809

这道题目我一定要好好吐槽一下,二维char数组表示成一维string,用来表示状态,然后求sg函数值用记忆化搜索,然后就一直WA,心好累差点怀疑人生,QAQ。后来发现记忆化搜索代码加上 if(vis[str])return sg[str]; 就WA,所以肯定这里出问题,后来一想,这种状态表示有毒,例如5x4与4x5的矩阵显然不同,但是展开成一维string时显然可以得到相同string,所以二维展一维时除了内容,还要加上R,C两个参数。可是这样就要用结构体,想想acm中处理字符串的技巧,其实在二维数组表示成string时,在末尾加上一个区别的符号就行了。这样就可以写最正宗的记忆化搜索了。

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
char g[55][55];
mapsg;
mapvis;
string ss;
int R,C;
string tostr(){
    ss="";
    for(int i=0;i


你可能感兴趣的:(博弈)