Loading

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;
}
posted @ 2022-04-26 16:48  dgsvygd  阅读(89)  评论(0编辑  收藏  举报