题目描述
校园里在上活动课,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[][]; int main()
{
cin >> n;
for(register int i = ; i <= n; ++i)
{
for(register int j = ; j <= i; ++j)
{
dp[i][j] = dp[i][j - ] | (dp[i - j][min(j << , i - j)] ^ );
}
}
cout << dp[n][];
return ;
}
参考程序