Position:


List

Description

  • 大意:有n堆石子,每堆石子个数已知,两人轮流从中取石子,每次可取的石子数x满足x属于集合S(k) = {s1,s2,s3…sk-1},问先拿者是否有必胜策略?
  • 普通Nim取石子游戏但加了一些限制条件,比如每次只能取S={s1,s2,s3……},就把前驱的条件改一下就行。

Knowledge

Sprague-Grundy Function-SG函数–博弈论
博弈论也是最近新学的知识,上面是一个写得很好的博客。
简单脑补:对于公平博弈(一般是NIM游戏),我们有一个重要的工具————就是SG函数。
SG函数的定义:
必败态的sg值为0,其余态的sg值为其后继状态的sg值的mex和。
其中mex和操作(mex{a1,a2,a3,…,ar})的含义是a1,a2,a3,…,ar中最小的没出现过的自然数。
而对于组合游戏(就是由若干个子游戏组合而成,每个子游戏之间状态独立,每次操作任选一个子游戏操作),其sg值为所有子游戏sg值的异或和。如果一个状态求得sg值为0,则为必败态,否则为必胜态。(证明略,大致是因为先手总能通过一步使sg不为0的状态变为0,而sg为0的状态只能变成sg不为0的状态,最后不能操作的状态sg也为0)而一般sg都是打表找规律,常用分析方法:(1) 等差分析(2) 等比分析(3) 特定数值位置分析(4) 奇偶位置分析。对于多组数据都不同就要暴力求,如本题。

Solution

分析:
1.可将问题转化为n个子问题,每个子问题分别为:
从一堆x颗石子中取石子,每次可取的石子数为集合S(k)中的一个数
2.分析(1)中的每个子问题,易得:SG(x)=mex(SG[(x-s[i]>0)])(k>=i>=1)
3.后面就是SG函数的应用,根据Sprague-Grundy Therem:g(G)=g(G1)^g(G2)^g(G3)^…^g(Gn)即游戏的和的SG函数值是它的所有子游戏的SG函数值的异或,即SG(G) = SG(x1)^SG(x2)^…^SG(xn),故若SG(G)=0那么必输。

Notice

memset:①比for快②#include - cstring
map复杂度加一个log,对于加入的数少的情况用,else flag数组。

Code

// <S-Nim.cpp> - 08/03/16 20:18:06
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is. #include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
#define EPS 1e-10
using namespace std;
typedef long long LL;
const int MAXN=;
const int MAXM=;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline int getint() {
register int w=,q=;register char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-')q=,ch=getchar();
while(ch>=''&&ch<='')w=w*+ch-'',ch=getchar();
return q?-w:w;
}
int n,T,sg[MAXN],m,ans,s[MAXN];
inline int mex(int x){
//map<int,bool>f;
bool f[MAXN];
memset(f,,sizeof(f));//fast <cstring>
int temp;
for(int i=;i<=n;i++){
temp=x-s[i];
if(temp>=){
if(sg[temp]==-)sg[temp]=mex(temp);
f[sg[temp]]=;
}
}
for(int i=;;i++)if(!f[i])return i;
}
inline int SG(int x){
if(sg[x]==-)sg[x]=mex(x);
return sg[x];
}
int main()
{
freopen("S-Nim.in","r",stdin);
freopen("S-Nim.out","w",stdout);
while(n=getint(),n){
for(int i=;i<=n;i++)s[i]=getint();
sg[]=;
for(int i=;i<MAXN;i++)sg[i]=-;
T=getint();
while(T--){
m=getint();ans=;
while(m--)ans^=SG(getint());
if(ans)printf("W");else printf("L");
}
printf("\n");
}
return ;
}

【Poj2960】S-Nim & 博弈论的更多相关文章

  1. (转载)Nim博弈论

    最近补上次参加2019西安邀请赛的题,其中的E题出现了Nim博弈论,今天打算好好看看Nim博弈论,在网上看到这篇总结得超级好的博客,就转载了过来. 转载:https://www.cnblogs.com ...

  2. hdu 3032 Nim or not Nim? 博弈论

     这题是Lasker’s Nim. Clearly the Sprague-Grundy function for the one-pile game satisfies g(0) = 0 and g( ...

  3. POJ2960 S-Nim 【博弈论】

    Description Arthur and his sister Caroll have been playing a game called Nim for some time now. Nim ...

  4. POJ2068 Nim 博弈论 dp

    http://poj.org/problem?id=2068 博弈论的动态规划,依然是根据必胜点和必输点的定义,才明白过来博弈论的dp和sg函数差不多完全是两个概念(前者包含后者),sg函数只是mex ...

  5. zoj 3591 Nim 博弈论

    思路:先生成序列再求异或,最多的可能为n*(n+1)/2: 在去掉其中必败的序列,也就是a[i]=a[j]之间的序列. 代码如下: #include<iostream> #include& ...

  6. poj 2068 Nim 博弈论

    思路:dp[i][j]:第i个人时还剩j个石头. 当j为0时,有必胜为1: 后继中有必败态的为必胜态!!记忆化搜索下就可以了! 代码如下: #include<iostream> #incl ...

  7. poj 2975 Nim 博弈论

    令ans=a1^a2^...^an,如果需要构造出异或值为0的数, 而且由于只能操作一堆石子,所以对于某堆石子ai,现在对于ans^ai,就是除了ai以外其他的石子 的异或值,如果ans^ai< ...

  8. POJ2975 Nim 博弈论 尼姆博弈

    http://poj.org/problem?id=2975 题目始终是ac的最大阻碍. 问只取一堆有多少方案可以使当前局面为先手必败. 显然由尼姆博弈的性质可以知道需要取石子使所有堆石子数异或和为0 ...

  9. 【BZOJ】4147: [AMPPZ2014]Euclidean Nim

    [算法]博弈论+数论 [题意]给定n个石子,两人轮流操作,规则如下: 轮到先手操作时:若石子数<p添加p个石子,否则拿走p的倍数个石子.记为属性p. 轮到后手操作时:若石子数<q添加q个石 ...

随机推荐

  1. nginx_location用法总结

    location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 因为所有的地址都以 / 开头,所以这条规则将匹配 ...

  2. 实现加载页Loading Page 的几种方法

    网页也可以像原生应用那样加入进度条或者其他的loading效果带来更好的等待体验,这里归纳几种我收集的实现loading page的方法,这几种方法在交互上都有利有弊,适用于不同应用.(PS:以下方法 ...

  3. ThinkPHP---ue编辑器

    [一]简介 (1)介绍 一款百度开发的JS插件 ue编辑器,全称Ueditor(翻译为你的编辑器),百度开发的在线编辑器,是一款在线编辑器软件,在线编辑器又称为“富文本编辑器”. 国外也有一款类似的编 ...

  4. 01Hypertext Preprocessor

    Hypertext Preprocessor PHP即Hypertext Preprocessor是一种被广泛使用的开放源代码多用途动态交互性站点的强有力的服务器端脚本语言尤其适用于 Web开发人员可 ...

  5. API Studio 5.1.2 版本更新:加入全局搜索、支持批量测试API测试用例、读取代码注解生成文档支持Github与码云等

    最近在EOLINKER的开发任务繁重,许久在博客园没有更新产品动态了,经过这些日子,EOLINKER又有了长足的进步,增加了更多易用的功能,比如加入全局搜索.支持批量测试API测试用例.读取代码注解生 ...

  6. BigDecimal运算

    BigDecimal由任意精度整数未缩放值和32位整数级别组成 . 如果为零或正数,则刻度是小数点右侧的位数. 如果是负数,则数字的非标定值乘以10,以达到等级的否定的幂. 因此,BigDecimal ...

  7. zabbix登录密码重置方法

    注:由于账号较多,难免忘记账号,下面是找回zabbix登录密码的过程. 一.登录zabbix数据库 [root@123 ~]# mysql -uroot -p密码 二.修改zabbix密码 mysql ...

  8. 运行/调试你的PHP代码

    前言 没有任何一名程序员可以一气呵成.完美无缺的在不用调试的情况下完成一个功能或模块.调试实际分很多种情况.本篇文章我分享下自己在实际开发工作中的经验,我个人理解,调试分三种,注意我所讲的是调试并非测 ...

  9. 团队一致性的PHP开发环境之Vagrant

    Vagrant 简介 Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境. 它的主要意义是让所有开发人员都使用和线上服务器一样的环境,本质上和你新建一个虚拟机 安装 # https: ...

  10. python输出带颜色字体详解

    在python开发的过程中,经常会遇到需要打印各种信息.海量的信息堆砌在控制台中,就会导致信息都混在一起,降低了重要信息的可读性.这时候,如果能给重要的信息加上字体颜色,那么就会更加方便用户阅读了. ...