博弈论
穆梓先生
人之为学有难易乎?学之则难者亦易矣,不学则易者亦难矣!
展开
-
hdu 2147 kiki's game
传送门: 题目大意:就是有一个游戏,在一个n*m的矩阵中起始位置是(1,m),走到终止位置(n,1);游戏规则是只能向左,向下,左下方向走,想走到终点的为获胜者。 巴什博弈的资料:只要把PN状态图描绘出来就行了:P点:就是P个石子的时候,对方拿可以赢(自己输的)N点:就是N个石子的时候,自己拿可以赢现在关于P,N的求解有三个规则(1):最终态都是P(2):按照游戏规则,到达当前态的前态都是N的...转载 2018-05-02 11:01:47 · 93 阅读 · 0 评论 -
nyoj 913 取石子(十)
sg函数打表//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++) { memset(hash,0,si...转载 2018-05-04 15:33:06 · 123 阅读 · 0 评论 -
hdu 1907 && hdu 2509
传送门1907#include <iostream>using namespace std;int main() { /** * 充裕堆: 火柴根数 > 1 * 孤单堆: 火柴根数 = 1 */ int sum1; //充裕堆的个数 int sum2; //孤单堆的个数 int ans; //异或.(用来判断是否是奇异局势) int t; sc...转载 2018-05-03 20:46:18 · 130 阅读 · 0 评论 -
hdu 1536 && hdu 1944 S-Nim(Nim博弈 )
第一行给出可行操作集合大小为k,然后k个数表示一次能在一堆里取这些数量的石子。先拿完者赢。第二行一个数m表示将会进行m次游戏。下面m行,每行第一个数n表示石子的堆数,后面n堆石子的数量。每次游戏先手赢输出W,否则输出L。每个样例所有游戏次数输出在一行。求SG函数模板递归//N为一堆里最大石子数量//M为可操作集合的最大数量//x为实际一堆里多少石子//k为实际可操作集合s为多大 //注意:...转载 2018-05-03 19:27:35 · 147 阅读 · 0 评论 -
hdu 5795 A Simple Nim(nim博弈)
可以看出,当x%8==0,是sg(x)=x-1 ,x%8==7 时,sg(x)=x+1sg打表程序#include <iostream> #include <cstring>#include <cstdio>#include <algorithm>using namespace std;int main() { int i, j, k;...原创 2018-05-03 16:53:49 · 126 阅读 · 0 评论 -
hdu 3032 Nim or not Nim?
题目大意:Alice和Bob轮流取N堆石子,每堆S[i]个,Alice先,每一次可以从任意一堆中拿走任意个石子,也可以将一堆石子分为两个小堆。先拿完者获胜。(1 ≤ N ≤ 10^6, 1 ≤ S[i] ≤ 2^31 - 1)解题思路:对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Grundy函数g如下:g(x)=mex{ g(y) | y是x的后继 },这里的g(x)即sg[x...原创 2018-05-03 16:16:59 · 95 阅读 · 0 评论 -
hdu 1848 Fibonacci again and again
博弈论SG函数讲解#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 1005; int f[N];//可以取走的石子个数 int sg[N];//0~n的SG函数值 int Hash[N]; ...转载 2018-05-03 15:45:03 · 92 阅读 · 0 评论 -
hdu 3389 Game(Nim)
传送门首先在纸上画了一下转移图:1 3 4号盒子是不能够再转移卡片到其他盒子中去了的,其他盒子中的卡片经过若干步的转移最终也一定会转移到1 3 4号盒子中去。具体来说,n % 6 == 0 或 2 或 5的盒子,经过奇数步转移到1 3 4中去,其他的则须经过偶数步才能转移过去。 下面来证明,所有卡片都在偶数步盒子中是必败状态。因为不论先手将偶数步的盒子中卡片移走了多少,后手一定可以把这些卡片再往前...转载 2018-05-03 15:38:00 · 82 阅读 · 0 评论 -
hdu 1850 Being a Good Boy in Spring Festival(nim 博弈输出方案数)
#include<stdio.h>using namespace std;int a[105];int main(){ int n; while(scanf("%d",&n)&&n){ int tem=0; for(int i=0;i<n;i++){ int x; scanf("%d",&x); a[i]=...原创 2018-05-02 20:13:02 · 131 阅读 · 0 评论 -
hdu 2177 取(2堆)石子游戏(威佐夫博弈)
威佐夫博弈原理#include<cstdio>#include<cmath> #include<algorithm>using namespace std;int main(){ int a,b; while(~scanf("%d%d",&a,&b)&&(a||b)){ if(a>b) swap(a,b);..转载 2018-05-02 16:29:58 · 141 阅读 · 0 评论 -
hdu 1527 取石子游戏(威佐夫博弈)
威佐夫博弈(Wythoff Game):有两堆各若干的物品,两人轮流从其中一堆取至少一件物品,至多不限,或从两堆中同时取相同件物品,规定最后取完者胜利。直接说结论了,若两堆物品的初始值为(x,y),且x<y,则另z=y-x;记w=(int)[((sqrt(5)+1)/2)*z ];若w=x,则先手必败,否则先手必胜。#include<stdio.h>#include<...原创 2018-05-02 15:26:21 · 179 阅读 · 0 评论 -
hdu 2516 取石子游戏
斐波那契博弈:有一堆物品,两人轮流取物品,先手最少取一个,至多无上限,但不能把物品取完,之后每次取的物品数不能超过上一次取的物品数的二倍且至少为一件,取走最后一件物品的人获胜。结论是:先手胜当且仅当n不是斐波那契数(n为物品总数)#include<stdio.h>using namespace std;#define N 55 int f[N];void init(){ f[...原创 2018-05-02 15:16:54 · 104 阅读 · 0 评论 -
hdu 3863 No Gambling
题意:给你一个大小为n的图,点的分布如上图所示,然后先手要建立一条路使从最左边连接到最右边,后手要建立一条路从最上边连接到最下边,问谁能赢.思路:画一下会发现,是先手必胜的,如果我们考虑后手一直都在堵先手的路,因为先手会比后手多走一步,所以说先手到达最右边是没法堵的,因为游戏已经结束了.#include<stdio.h>using namespace std;int main(...原创 2018-05-02 15:05:40 · 114 阅读 · 0 评论 -
hdu 2149 Public Sale
#include<stdio.h>using namespace std;int main(){ int n,m; while(scanf("%d%d",&m,&n)!=EOF){ if(m%(n+1)==0) { printf("none\n"); continue; } else{ int r=m%(n+1);...原创 2018-05-02 11:22:24 · 92 阅读 · 0 评论 -
hdu 2897 邂逅明下
bash博弈变形2:初始状态下有石子n个,除最后一次外其他每次取物品个数必须在[p,q]之间,最后一次取硬币的人输。(HDU 2897) 这题状态稍微复杂一些,并且胜负条件与之前相反,一般bash博弈里每次取个数可以看作在[1,m]之间,胜负手判断为 n % (1+m) ,因此我们可以猜想每次取[p,q]的胜负手判断为 n % (p+q) ,通过验证猜想我们可以发现如下策略:n=k∗(转载 2018-05-02 11:11:44 · 100 阅读 · 0 评论 -
hdu 1846 Brave Game
#include<stdio.h>using namespace std;int main(){ int t; scanf("%d",&t); while(t--){ int n,m; scanf("%d%d",&n,&m); if(n%(m+1)==0) printf("second\n"); else printf("firs.原创 2018-05-02 11:06:03 · 109 阅读 · 0 评论 -
hdu 1847 Good Luck in CET-4 Everybody!
sg函数打表#include<stdio.h>#include<string.h> using namespace std;#define N 55 int f[N],sg[N],hash[N]; void getSG1(int n) //第一堆每次只能取2的幂次(即:1,2,4,8,16…);{ f[1]=1; for(int i=2;i&...原创 2018-05-02 11:05:07 · 115 阅读 · 0 评论 -
hdu 1896 stone
题目大意:Tang和Jiang轮流写数字,Tang先写,每次写的数x满足1<=x<=k,Jiang每次写的数y满足1<=y-x<=k,谁先写到不小于n的数算输。结论:r=(n-1)%(k+1),r=0时Jiang胜,否则Tang胜。#include<stdio.h>using namespace std;int main(){ int n,k; whi...原创 2018-05-02 11:03:01 · 164 阅读 · 0 评论 -
hdu 1079 Calendar Game
2种操作,日+1,或月+1,(除了几个特殊日期外)均能改变月+日的奇偶性,而目标11.4,月+日为奇数,所以只要起始日期的月+日为偶数就可能赢。而两个特殊日期(9.30,11.30),尽管月+日为奇数,但下一步仍然可以得到奇数。#include<stdio.h>using namespace std;int main(){ int t; int y,m,d; scanf(...转载 2018-05-04 16:18:39 · 128 阅读 · 0 评论