SRM 624 D2L3: GameOfSegments, game theory, SD-Grundy theorem, Nimber, spraguegrundy
Question: http://community.topcoder.com/stat? C = problem_statement & pm = 13204 & rd = 15857
This topic needs to use the classic theory in game theory. The following is a summary of relevant theories:
Impartial Game: a fair Game. The two sides are the same except who starts the Game first.
Nim: a classic Impartial Game. Many games can be equivalent to Nim.
Nimber (Grundy numbers): number of game states. Each status should be a unique Nimber during the game's process.
The pair-grundy theorem: For an Impartial Game, its equivalent number of Nimber in the Game is equal to the value of the Mex function in all its successor States.
Mex: for a set of S, if G is the complement set of S, then Mex {S} = min {G }.
The number of Nimbers in the current game State needs to be obtained based on the theorem of SD-Grundy, and then the Nimbers values in all subsequent states need to be obtained. This is particularly useful when there are multiple "sub-Impartial Games" at the same time, and the number of Nimber in each "sub-Game" status is operated differently or differently, the number of Nimber in this status.
The Code is as follows:
#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <iostream>#include <sstream>#include <iomanip>#include <bitset>#include <string>#include <vector>#include <stack>#include <deque>#include <queue>#include <set>#include <map>#include <cstdio>#include <cstdlib>#include <cctype>#include <cmath>#include <cstring>#include <ctime>#include <climits>using namespace std;#define CHECKTIME() printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC)typedef pair<int, int> pii;typedef long long llong;typedef pair<llong, llong> pll;#define mkp make_pair#define FOREACH(it, X) for(__typeof((X).begin()) it = (X).begin(); it != (X).end(); ++it)/*************** Program Begin **********************/class GameOfSegments {public: int winner(int N) { int Nimbers[1001]; Nimbers[0] = Nimbers[1] = 0; for (int i = 2; i <= N; i++) { set <int> options; for (int j = 0; j <= i - 2; j++) { options.insert(Nimbers[j] ^ Nimbers[i - j - 2]); } int r = 0; while (options.count(r)) { ++r; } Nimbers[i] = r; } return (Nimbers[N] > 0 ? 1 : 2); }};/************** Program End ************************/
Refer:
Http://www.cnblogs.com/fishball/archive/2013/01/19/2866311.html
Http://www.cnblogs.com/hsqdboke/archive/2012/04/20/2459796.html
Http://www.cnblogs.com/hsqdboke/archive/2012/04/21/2461034.html