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;
}
相關文章
- 博弈論基礎之sg函式與nim函式
- NIM遊戲/SG函式遊戲函式
- 記憶化搜尋
- ECNU OJ 3354 領外賣(博弈-SG函式)函式
- HDU 5795 A Simple Nim (SG函式+打表找規律)函式
- 博弈論:公平組合遊戲(Nim 遊戲 & SG 定理)學習筆記遊戲筆記
- HDU 1848 Fibonacci again and again (尼姆博弈+sg函式)AI函式
- LightOj1296Again Stone Game(手推SG函式)AIGAM函式
- C++記憶化搜尋C++
- 【博弈論】組合遊戲及SG函式淺析遊戲函式
- HDU 6415(dp/記憶化搜尋)
- 兩個需要求 sg 函式的樹上博弈問題函式
- POJ 2975 Nim
- 【Leetcode】1340. Jump Game V 【動態規劃/記憶性搜尋】LeetCodeGAM動態規劃
- Pots POJ – 3414 (搜尋+記錄路徑)
- 【leetcode 1510 石子游戲】【記憶化搜尋】LeetCode
- Leetcode 292. Nim GameLeetCodeGAM
- POJ 1129 Channel Allocation (暴力搜尋)
- 記憶搜尋解救滑雪問題
- 一類適合記憶化搜尋的區間dp
- C - Digital Path 計蒜客 - 42397(dp記憶化搜尋)Git
- 【簡單搜尋】POJ 2251 Dugeon MasterAST
- 【leetcode 3149. 找出分數最低的排列】記憶化搜尋LeetCode
- POJ - 2236 Wireless Network (kuangbin - 簡單搜尋)
- HDU 1848 Fibonacci again and again(SG函式)AI函式
- WeetCode3 暴力遞迴->記憶化搜尋->動態規劃遞迴動態規劃
- 【博弈論】HDU - 7216 Triangle GameGAM
- ACM-ICPC 2018 南京賽區網路預賽__K The Great Nim Game【博弈論+費馬小定理+DP】ACMGAM
- 如何高效記憶字串函式字串函式
- 常用記憶體操作函式記憶體函式
- POJ1915,雙向寬度優先搜尋
- 組合數的計算(利用楊輝三角/記憶化搜尋)
- ES 筆記十七:結構化搜尋筆記
- Golang記憶體分配內建函式之new函式Golang記憶體函式
- 手撕記憶體操作函式記憶體函式
- 每日五個 PHP 函式記憶PHP函式
- 最佳路徑搜尋(二):啟發式搜尋(代價一致搜尋(Dijkstra search),貪心搜尋,A*搜尋)
- A*啟發式搜尋
- 【記憶優化搜尋/dp】HDU - 6415 - 杭電多校第九場 - Rikka with Nash Equilibrium優化UI