Description
被污染的灰灰草原上有羊和狼。有N只动物围成一圈,每只动物是羊或狼。
该游戏从其中的一只动物开始,报出[1,K]区间的整数,若上一只动物报出的数是x,下一只动物可以报[x+1,x+K]区间的整数,游戏按顺时针方向进行。每只动物报的数字都不能超过M。若一只动物报了M这个数,它所在的种族就输了。问以第i只动物为游戏的开始,最后哪种动物会赢?
Input
第一行输入三个正整数N,M,K。
接下来一行N个正整数,分别表示N只动物的种类,以顺时针的方向给出。0代表羊,1代表狼。
Output
一行输出N个整数,表示若从第i只动物开始,赢的动物的种类。同上,0代表羊,1代表狼。
Sample Input
Input 1
2 9 2
0 1
Input 2
6 499 5
1 0 0 1 1 0
Input 3
10 100 10
0 0 0 1 1 1 1 0 1 1
Sample Output
Output 1
0 1
Output 2
0 1 1 1 1 0
Output 3
1 1 1 1 1 1 1 1 1 1
Data Constraint
对于60%的数据,1 ≤ N, M, K ≤ 500。
对于100%的数据,1 ≤ N, M, K ≤ 5000。
思路
一开始以为是SG函数,结果发现根本不行(为什么不行?各位大佬肯定知道啦!),于是考虑DP
设f[i][j]为第i个动物,报了j,是否有必胜策略。
预处理:f[][m]=0
对于第i只动物,当f[i+1][j+1..j+k]存在必胜策略,显然,若是同种,则f[i][j]=1,否则,f[i][j]=0反之亦然。
可是判断j+1..j+k是否存在必胜策略需要O(n)时间,所以我们要用后缀和维护。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=5077;
int n,m,k,s[maxn][maxn],f[maxn][maxn],a[maxn];
int main()
{
freopen("vode.in","r",stdin); freopen("vode.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
f[i][m]=0;
}
for(int j=m-1; j>=1; j--)
{
for(int i=n; i>=1; i--)
{
if(s[i%n+1][j+1]-s[i%n+1][min(j+k,m)+1]) f[i][j]=1;
if(a[i]!=a[i%n+1]) f[i][j]^=1;
s[i][j]=s[i][j+1]+f[i][j];
}
}
for(int i=1; i<=n; i++) printf("%d ",(s[i][1]-s[i][k+1])?a[i]:a[i]^1);
}