题解
- 首先,可以破坏为链,在n后返回到1
- 设f[i][j]为前i个动物 报的数字为j 是否有必胜策略(0表示没有 1表示有)
- 那么怎么求f数组
- 如果当前i和i+1是同一种动物
- 那只要判断f[i+1][j+1...+k]有没有必胜策略,如果有f[i][j]=1
- 如果当前i和i+1不是同一种动物
- 那只要判断f[i+1][j+1...+k]有没有必胜策略,如果有f[i][j]=0
- 那么判断f[i+1][j+1...+k]有没有必胜策略,只要用一个后缀和统计就好了
代码
1 #include <cstdio>
2 #include <iostream>
3 #include <cstring>
4 #include <cmath>
5 using namespace std;
6 int f[5010][5010],sum[5010][5010],n,m,q,a[5010];
7 int quan(int x) {if (x==n) return 1; else return x+1;}
8 int main()
9 {
10 //freopen("vode.in","r",stdin);
11 //freopen("vode.out","w",stdout);
12 scanf("%d%d%d",&n,&m,&q);
13 for (int i=1;i<=n;i++) scanf("%d",&a[i]);
14 for (int j=m-2;j>=0;j--)
15 for (int i=1;i<=n;i++)
16 {
17 int mn=j+1,mx=min(j+q,m-1);
18 f[i][j]=(((a[i]^a[quan(i)])&&sum[quan(i)][mn]-sum[quan(i)][mx+1]<mx-mn+1)||(!(a[i]^a[quan(i)])&&sum[quan(i)][mn]-sum[quan(i)][mx+1]>0));
19 sum[i][j]=sum[i][j+1]+f[i][j];
20 }
21 for (int i=1;i<=n;i++) printf("%d ",(1-(f[i][0]^a[i])));
22 return 0;
23 }