GHOJ 380 放球游戏B

题目描述

        校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球。第一个人只能放1个球,之后的人最多可以放前一个人的两倍数目的球,至少放1个球。最后面对没有空格而不能放球的人为输。

        现在Red先走,问他有没有必胜的策略?

        比如:N=4时,Red必胜。

输入格式

        一行,一个整数N(2<N<100)。

输出格式

        一行,一个整数。如果Red必胜输出1,否则输出0。

输入样例

7

输出样例

0

 

题解

        这里不好直接推公式,那我们就用dp。

        用$dp[i][j]$表示有$i$个格子,此时的先手可以放最多$j$个球的情况下是否必胜。

        容易想到,如果$dp[i][j-1]$为真,那么$dp[i][j]$也为真。

        但是还少了一种情况,如果放了$j$个球后,后手必胜,则先手必输,即如果$dp[i-j][min(2j, i-j)]$为真,则$dp[i][j]$为假。

#include <iostream>

using namespace std;

int n;
int dp[105][105];

int main()
{
    cin >> n;
    for(register int i = 1; i <= n; ++i)
    {
        for(register int j = 1; j <= i; ++j)
        {
            dp[i][j] = dp[i][j - 1] | (dp[i - j][min(j << 1, i - j)] ^ 1);
        }
    }
    cout << dp[n][1];
    return 0;
}
参考程序
原文地址:https://www.cnblogs.com/kcn999/p/10777294.html