打表: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 //f[]:可以取走的石子个数 //sg[]:0~n的SG函数值 //hash[]:mex{} int f[N],sg[N],hash[N]; void getSG(int n) { int i,j; memset(sg,0,sizeof(sg)); for(i=1;i<=n;i++
sg(a -1, b, c, d));if(b >=2) f =min(f,sg(a, b -2, c +1, d));if(b >0&& c >0) f =min(f,sg(a, b -1, c -1, d +1));return1- f;
题解: 博弈论 + SG函数 + 分段打表 暴力的求SG函数会超时,正解是先处理出10^5以内的SG值,可以发现sg函数值成段出现. 根据sg函数值成段出现的特点,构造函数sg[lower_bound(a, a+6, i)-a]。 根据10^5以内的SG值,使用该函数,容易计算全部SG值(<=777777777777) #include"stdafx.h"#include<iostream>#i...
这次cf莫名奇妙变成多组数据输入,有点不习惯,前面的题加return 0 wa了两发。。这个题刚开始看错题了,以为是从左往右走,但是不影响我sg打表:dp[i]为0代表着这个位置出发,后手能赢,为1代表着这个位置先手能赢。那么从后手能赢推导出哪些位置为1.。。。找规律,没找到规律(菜呀),看别人的博客才知道规律。。
还可以用SG函数打表找出我们所要的结果NP 图 #include<stdio.h>#include<string.h>constintsz=200;intSG[sz][sz];intdir[3][2]={-1,0,0,1,-1,1};intn,m;voidget_sg(){inti,j;memset(SG,0,sizeof(SG));for(i=n;i>=1;i--)for(j=1;j<=m;j++){if(!SG[i][j])for(intk=0;k<...
HDU 3032 nim or not nim(sg函数打表) 题意: 有n堆石子,每次可以从一堆石子里面取至少1个石子,或者将一堆石子分为两堆,问先手必赢还是必输 题解: 用SG函数打表找规律,sg[0]=0;sg[1]=1;当有2个石子时,经过操作后可以变成0个,1个,或者(1,1)这三种状态,。。。所有堆的石子个数的sg异或为0则必...
intf[MAXN],sg[MAXN]; voidinit(){//得到1000以内的fibonacci数列 f[]=; f[]=; for(inti=;;i++){ f[i]=f[i-]+f[i-]; if(f[i]>){ break; } } } voidget_sg(){//sg函数打表 for(inti=;i<=;i++){ intvis[MAXN];
Light OJ 1296:Again Stone Game(SG函数打表找规律) Alice and Bob are playing a stone game. Initially there are n piles of stones and each pile contains some stone. Alice stars the game and they alternate moves. In each move, a player has to select any pile and should remove at least ...
const int N=10008;//N为所有堆最多石子的数量 int f[108],sg[N];//f[]用来保存只能拿多少个,sg[]来保存SG值 bool hash[N];//mex{} void sg_solve(int t,int N) { int i,j; memset(sg,0,sizeof(sg)); for(i=1;i<=N;i++) { memset(hash,0,sizeof(hash)); for(j=1;j<=t&&...