POJ 2311-Cutting Game(Nim博弈-sg函式/記憶化搜尋)
Cutting Game
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3632 | Accepted: 1352 |
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 the victim. To get away from suffering playing such a dull game, Erif Nezorf requests your help. The game uses a rectangular paper that consists of W*H grids. Two players cut the paper into two pieces of rectangular sections in turn. In each turn the
player can cut either horizontally or vertically, keeping every grids unbroken. After N turns the paper will be broken into N+1 pieces, and in the later turn the players can choose any piece to cut. If one player cuts out a piece of paper with a single grid,
he wins the game. If these two people are both quite clear, you should write a problem to tell whether the one who cut first can win or not.
Input
The input contains multiple test cases. Each test case contains only two integers W and H (2 <= W, H <= 200) in one line, which are the width and height of the original paper.
Output
For each test case, only one line should be printed. If the one who cut first can win the game, print "WIN", otherwise, print "LOSE".
Sample Input
2 2 3 2 4 2
Sample Output
LOSE LOSE WIN
Source
POJ Monthly,CHEN Shixi(xreborner)
當一張w*h的紙被分成兩張時,假設所得的兩張紙的sg值分別為sg1和sg2,
則它們對應的狀態的sg值可以表示為sg1 XOR sg2。
在Nim中,不論有幾堆石子、初始狀態是怎樣的,只要XOR的結果相同,那麼對勝負是沒有影響的。這裡也一樣,只要SG值相同,即使發生分割,只要堆分割後的各部分取XOR,就可以利用這一個SG值來代表幾個遊戲複合而成的狀態,SG值也可以同樣地計算。
瞭解了會發生分割的遊戲的處理方法之後,只要像以前的問題一樣,列舉所有一步能夠到達的狀態的SG值,就能夠計算SG值了。
題目意思:
有一張被分成w*h的格子的長方形紙張,兩人輪流沿著格子的邊界水平或垂直切割,將紙張分割成兩部分。切割了n次之後就得到了n+1張紙,每次都可以選擇切得的某一張紙再進行切割。最先切出只有一個格子的紙張(即有1*1格子的)的一方獲勝。當雙方都採取最優策略時,先手必勝還是必敗?解題思路:
初始只有一張紙,紙張的數量隨著切割而增加。當一張w*h的紙被分成兩張時,假設所得的兩張紙的sg值分別為sg1和sg2,
則它們對應的狀態的sg值可以表示為sg1 XOR sg2。
在Nim中,不論有幾堆石子、初始狀態是怎樣的,只要XOR的結果相同,那麼對勝負是沒有影響的。這裡也一樣,只要SG值相同,即使發生分割,只要堆分割後的各部分取XOR,就可以利用這一個SG值來代表幾個遊戲複合而成的狀態,SG值也可以同樣地計算。
瞭解了會發生分割的遊戲的處理方法之後,只要像以前的問題一樣,列舉所有一步能夠到達的狀態的SG值,就能夠計算SG值了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <set>
#include <algorithm>
using namespace std;
const int MAXN=202;
int mem[MAXN][MAXN];//記憶化搜尋用的陣列
int grundy(int w,int h)
{
if(mem[w][h]!=-1) return mem[w][h];//之前已經搜尋過了,可以直接返回記憶的值
set<int>s;
//保證邊長至少為2
for(int i=2; w-i>=2; ++i)//剪w邊
s.insert(grundy(i,h)^grundy(w-i,h));
for(int i=2; h-i>=2; ++i)//剪h邊
s.insert(grundy(w,i)^grundy(w,h-i));
int res=0;
while(s.count(res))
++res;
return mem[w][h]=res;
}
int main()
{
int w,h;
memset(mem,-1,sizeof(mem));//初始化
while(~scanf("%d%d",&w,&h))//輸入格子長寬
{
if(grundy(w,h)) puts("WIN");
else puts("LOSE");
}
return 0;
}
相關文章
- 博弈學習(一) NIM + SG函式函式
- 博弈論基礎之sg函式與nim函式
- NIM遊戲/SG函式遊戲函式
- HDU 1846-Brave Game(巴什博弈-SG函式)GAM函式
- 博弈論進階之SG函式函式
- 記憶化搜尋
- HDU1729 Stone Game (SG函式)GAM函式
- POJ 1579-Function Run Fun(記憶化搜尋-遞迴)Function遞迴
- HDU 5795 A Simple Nim (SG函式+打表找規律)函式
- C++記憶化搜尋C++
- 【博弈論】組合遊戲及SG函式淺析遊戲函式
- poj1179 區間dp(記憶化搜尋寫法)有巨坑!
- ECNU OJ 3354 領外賣(博弈-SG函式)函式
- 兩個需要求 sg 函式的樹上博弈問題函式
- HDU 2897-邂逅明下(博弈-SG函式打表找規律)函式
- 【Leetcode】1340. Jump Game V 【動態規劃/記憶性搜尋】LeetCodeGAM動態規劃
- codeforces 15C Industrial Nim(NIM 博弈)
- HDU 1848 Fibonacci again and again (尼姆博弈+sg函式)AI函式
- Codeforces 900D Unusual Sequences:記憶化搜尋
- LightOj1296Again Stone Game(手推SG函式)AIGAM函式
- HDU 1847-Good Luck in CET-4 Everybody!(博弈-SG函式/找規律)Go函式
- LeetCode-Nim GameLeetCodeGAM
- 博弈論入門之nim遊戲遊戲
- A Multiplication Game (博弈,規律)GAM
- 【leetcode 1510 石子游戲】【記憶化搜尋】LeetCode
- Leetcode 292. Nim GameLeetCodeGAM
- Flip Game(POJ 1753)GAM
- Nim遊戲(一堆/N堆)-博弈遊戲
- C - Digital Path 計蒜客 - 42397(dp記憶化搜尋)Git
- Codeforces 148D Bag of mice:概率dp 記憶化搜尋
- codeforces 505C. Mr. Kitayuta, the Treasure Hunter (記憶化搜尋)
- 【簡單搜尋】POJ 2251 Dugeon MasterAST
- POJ 1691 Painting A Board(dfs搜尋)AI
- 博弈論進階之Multi-SG
- 博弈論進階之Every-SG
- 組合數的計算(利用楊輝三角/記憶化搜尋)
- 共享記憶體函式記憶體函式
- poj 2478 尤拉函式函式