1230-Nim
問題概要
S個の石から1〜m[turn%(2*n)]個の石を互いにとっていくゲームをする.
最善を付くした時にどちらが勝つかを求めよ
解法
数は減るのでループが発生しないのでmin-max法をメモ化する
計算量はO(NS)
実装(C++)
#include <iostream> #include <cstring> using namespace std; int n,s,m[20]; int dp[2<<14][30]; int solve(int remain,int turn){ if(remain<=1){ if(turn%2==0)return 0; else return 1; }else{ int ans=0; if(dp[remain][turn%n]>=0)return dp[remain][turn%n]; if(turn%2==0){ for(int i=1;i<=m[turn%n];i++){ ans=max(ans,solve(remain-i,turn+1)); } }else{ ans=1; for(int i=1;i<=m[turn%n];i++){ ans=min(ans,solve(remain-i,turn+1)); } } return dp[remain][turn%n]=ans; } } int main() { while(cin>>n,n){ cin>>s; for(int i=0;i<2*n;i++){ cin>>m[i]; } n*=2; memset(dp,-1,sizeof(dp)); cout<<solve(s,0)<<endl; } return 0; }