poj 2311 Cutting Game nim与状态的grundy值

题意:

给一个w*h的矩形,两人轮流只能沿格子的边缘横剪或竖剪,最先剪出1*1的格子的人获胜,问先手必胜还是必败。

分析:

此题要求对grundy值有理解。一个全局状态的grundy值是对游戏中某个状态的有效的描述,grundy值描述了当前状态的所有后继状态,比如n堆石子的nim游戏的grundy值是a1^a2^...an。

代码:

//poj 2311
//sep9
#include <iostream>
#include <set>
using namespace std;
const int maxN=256;
int dp[256][256];

int grundy(int w,int h)
{
	if(dp[w][h]!=-1) return dp[w][h];
	set<int> s;
	for(int i=2;w-i>=2;++i) s.insert(grundy(i,h)^grundy(w-i,h));
	for(int i=2;h-i>=2;++i) s.insert(grundy(w,i)^grundy(w,h-i));
	int res=0;
	while(s.count(res)) res++;
	return dp[w][h]=res;
}

int main()
{
	memset(dp,-1,sizeof(dp));
	int w,h;
	while(scanf("%d%d",&w,&h)==2){
		if(grundy(w,h)!=0) puts("WIN");
		else puts("LOSE");
	}
	return 0;
} 
时间: 2024-10-21 11:33:45

poj 2311 Cutting Game nim与状态的grundy值的相关文章

POJ 2311 Cutting Game (sg函数)

给出一个N*M的纸片,每一次可以把一部分剪成两部分,谁剪出1*1的就赢了. http://poj.org/problem?id=2311 对于任何一个人,都不会先剪出1*n或者n*1,应该这样就必败了. 那我们考虑一个状态的后继中,最小的边也是2,这样就可以避免之前的问题,也不需要考虑类似ANTI-SG. 一旦出现2*2,2*3,3*2,这些都成了终止状态,不论怎么剪都会出现1*n,或者n*1 还是考察SG函数 # include<stdio.h> # include<algorithm

POJ 2311 Cutting Game [Multi-SG?]

传送门 题意:n*m的纸片,一次切成两份,谁先切出1*1谁胜 Multi-SG? 不太一样啊 本题的要求是后继游戏中任意游戏获胜就可以了.... 这时候,如果游戏者发现某一单一游戏他必败他就不会再玩了 $2*2,2*3,3*3$都不会再玩了(除非只剩下这样的纸片了),所以都可以认为是终止状态,必败 在此基础上按照Multi-SG递推就对了 #include <iostream> #include <cstdio> #include <algorithm> #includ

poj 2311 Cutting Game SG函数的运用 唉,,,

Cutting Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3227   Accepted: 1195 Description Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his e

poj 2311 Cutting Game (SG)

题意: 有一张W*H的纸片. 每人每次可以横着撕或者竖着撕,先撕出1*1那一方胜. 数据范围: W and H (2 <= W, H <= 200) 思路: 很好抽象出游戏图的模型,用SG解决.直接看代码. 代码: int dp[maxn][maxn]; int sg(int w,int h){ if(dp[w][h]!=-1) return dp[w][h]; bool g[maxn]; mem(g,false); for(int i=2;i<=w/2;++i) g[sg(i,h)^s

POJ - 2311 Cutting Game

Description Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his extraordinary wit. Recently Urej takes a great interest in a new game, and Erif Nezorf becomes th

poj 2425 A Chess Game grundy值

题意: 给一个拓扑图,在一些点上有棋子,两个玩家每次轮流将一颗棋子沿有向边移动一次,无法移动则失败. 分析: 理解nim和状态的grundy值两下就敲出来了. 代码: //poj 2425 //sep9 #include <iostream> #include <vector> using namespace std; const int maxN=1024; vector<int> g[maxN]; int vis[maxN]; int grundy[maxN]; i

POJ Cutting Game(Nim博弈+grundy数)

Description Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his extraordinary wit. Recently Urej takes a great interest in a new game, and Erif Nezorf becomes th

硬币游戏2&amp;&amp;Cutting Game——Grundy值

Grundy值 当前状态的Grundy值就是除任意一步所能转移到的状态的Grundy值以外的最小非负整数, 以硬币问题一为例,可写成: int init_grundy() { sg[0] = 0; for(int i = 1;i <= x;i++) //递推求前x个SG值 { set<int>st; for(int j = 0;j < k;j++) if(a[j] <= i) st.insert(sg[i - a[j]]); int g = 0; while(st.count

poj 3537 Crosses and Crosses 博弈论之grundy值

题意: 给1*n的格子,轮流在上面叉叉,最先画得3个连续叉叉的赢,问先手必胜还是必败. 分析: 求状态的grundy值(也就是sg值),具体怎么求详见代码,为什么这么求要自己想的,只可意会(别人都说去看game theory,呵呵). 代码: //poj 3537 //sep9 #include <iostream> #include <set> using namespace std; int grundy[2048]; int h[2048]; int get_grundy(i