标签:一个 策略 存在 clu pre mes tmp print include
n枚硬币排成一个圈。Alice和Bob轮流从中取一枚或两枚硬币。不过,取两枚时,所取的两枚硬币必须是连续的。硬币取走之后留下空格,相隔空格的硬币视为不连续。Alice开始先取,取走最后一枚硬币的获胜。当双方都采取最有策略时,谁会获胜?
不管,先爆搜找规律。
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; const int maxn = 50; int a[maxn], n; map<ll, int>mp; bool check() { bool flag = true; for(int i = 0;i < n;i++) if(a[i] == 0) flag = false; return flag; } ll state() { ll ret = 0; for(int i = 0;i < n;i++) ret = ret *2 + a[i]; return ret; } int dfs(int cnt) //必胜返回1,平局返回2,必败返回-1 { int& ret = mp[state()]; if(ret) return ret; if(check()) return ret=-1; if(cnt >= n) return ret=2; bool flag = false; //能否成平局 for(int i = 0;i < n;i++) { if(a[i]) continue; a[i] = 1; int tmp = dfs(cnt+1); a[i] = 0; if(tmp == -1) return ret=1; //后面存在必败态,先手必胜 if(tmp == 2) flag = true; //存在平局 if(a[(i+1)%n] == 0) { a[i] = 1; a[(i+1)%n] = 1; int tmp = dfs(cnt+2); a[i] = 0; a[(i+1)%n] = 0; if(tmp == -1) return ret=1; //后面存在必败态,先手必胜 if(tmp == 2) flag = true; //存在平局 } } return ret=(flag ? 2 : -1); } int main() { for(n=1;;n++) { memset(a, 0, sizeof(a)); mp.clear(); printf("%d %d\n", n, dfs(0)); } }
规律很明显,小于等于2先手赢,否则后手赢。
标签:一个 策略 存在 clu pre mes tmp print include
原文地址:https://www.cnblogs.com/lfri/p/11624198.html