[jzoj 5778]【NOIP提高A组模拟2018.8.8】没有硝烟的战争 (博弈论+dp)

传送门

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。

Solution

利用dp求出必胜策略类似SG?
PS:dp需要sum优化一下

Code

//By Menteur_Hxy
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define R(i,a,b) for(register int i=(b);i>=(a);i--)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
using namespace std;

char buf[1<<20],*p1=buf,*p2=buf;
int read() {
	int x=0,f=1; char c=getchar();
	while(!isdigit(c)) {if(c=='-')f=-f; c=getchar();}
	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
	return x*f;
}

const int N=5050;
int n,m,k;
int f[N<<1][N],da[N];

int nu(int x) {return x%n?x%n:n;}

int main() {
	freopen("vode.in","r",stdin);
	freopen("vode.out","w",stdout);
	n=read(),m=read(),k=read();
	F(i,1,n) da[i]=read();
	R(i,1,n+m-1) {
		int sum=0;
		R(j,1,m-1) {	
			if(da[nu(i)]==da[nu(i+1)]) f[i][j]=sum>0;
			else f[i][j]=(sum==0);
			sum+=f[i+1][j];
			if(j+k<=m) sum-=f[i+1][j+k];
		}
	}
//	R(i,1,n+m) {F(j,1,m) printf("%d",f[i][j]);puts("");}
	F(i,1,n) F(j,1,k) if(f[i][j]) {f[i][0]=1;break;}
	F(i,1,n) printf("%d ",f[i][0]?da[i]:da[i]^1);
	return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9445170.html