HDU-2516 取石子游戏
取石子游戏
有一堆石子,第一个人能取任意个,但不能全取完,接下来每个人取的数量至多不超过上一个人取的两倍
把最后一个石头拿走的为胜
博弈 打表
最后发现是斐波那契数列,后手必胜
AC代码
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int num[maxn];
map<ll, int>vis;
int main()
{
int n;
ll a = 1, b = 1, c = 1, l = 1e10 + 10;
while(c < l)
{
vis[c] = 1;
a = b;
b = c;
c = a + b;
}
while(cin >> n && n)
{
if(vis[n]) cout << "Second win" << endl;
else cout << "First win" << endl;
}
return 0;
}
暴力打表
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 110;
int dp[maxn][maxn];
int dfs(int i, int j)
{
if(j > maxn) return 1;
if(dp[i][j]) return dp[i][j];
if(j >= i) return dp[i][j] = 1;
if(i < 0) return -1;
int f = 0;
for(int k=1; k<=j; k++)
f = min(dfs(i - k, k * 2), f);
if(f == -1) dp[i][j] = 1;
else dp[i][j] = -1;
return dp[i][j];
}
int main()
{
int n = 0;
cin >> n;
for(int i=2; i<=n; i++)
{
int f = 0;
for(int j=1; j<i; j++)
{
f = max(f, dfs(i, j));
}
cout << i << " : ";
if(f) cout << "first" << endl;
else cout << "second" << endl;
}
return 0;
}