Description
被污染的灰灰草原上有羊和狼。有N只动物围成一圈,每只动物是羊或狼。
该游戏从其中的一只动物开始,报出[1,K]区间的整数,若上一只动物报出的数是x,下一只动物可以报[x+1,x+K]区间的整数,游戏按顺时针方向进行。每只动物报的数字都不能超过M。若一只动物报了M这个数,它所在的种族就输了。问以第i只动物为游戏的开始,最后哪种动物会赢?
该游戏从其中的一只动物开始,报出[1,K]区间的整数,若上一只动物报出的数是x,下一只动物可以报[x+1,x+K]区间的整数,游戏按顺时针方向进行。每只动物报的数字都不能超过M。若一只动物报了M这个数,它所在的种族就输了。问以第i只动物为游戏的开始,最后哪种动物会赢?
Input
第一行输入三个正整数N,M,K。
接下来一行N个正整数,分别表示N只动物的种类,以顺时针的方向给出。0代表羊,1代表狼。
接下来一行N个正整数,分别表示N只动物的种类,以顺时针的方向给出。0代表羊,1代表狼。
Output
一行输出N个整数,表示若从第i只动物开始,赢的动物的种类。同上,0代表羊,1代表狼。
Solutions
我们可以设 dp[i][j]=0/1 来表示第 i 只动物报的数字是 j,是否有必胜策略。
0 表示没有必胜策略,1 表示有。
边界条件就是 dp[][m]=0 Dp[i][j]怎么求?
假如 i 和 i+1 是同一个种群,那么只需要判断 dp[i+1][j+1…j+k]是否存在必胜策略,如果存在,那么 dp[i][j]=1.
同样的,假如 i 和 i+1 不是同一个种群,那么只需要判 断 dp[i+1][j+1…j+k]是否存在必胜策略,如果存在,那 么 dp[i][j]=0.
判断 dp[i+1][j+1…j+k]是否存在必胜策略,只需要用一 个后缀和辅助即可。
然后对于每一个动物,你只需要知道,dp[i][1…k]是否 有必胜策略就行了。
代码
1 var 2 n,m,k:longint; 3 a:array [0..5001] of longint; 4 f,ans:array [0..5001,0..5001] of longint; 5 function min(o,p:longint):longint; 6 begin 7 if o<p then exit(o); 8 exit(p); 9 end; 10 11 procedure init; 12 var 13 i:longint; 14 begin 15 readln(n,m,k); 16 for i:=1 to n do 17 read(a[i]); 18 end; 19 20 procedure main; 21 var 22 i,j,l:longint; 23 begin 24 fillchar(f,sizeof(f),0); 25 for j:=m-2 downto 0 do 26 for i:=1 to n do 27 begin 28 l:=i+1; 29 if l>n then l:=1; 30 if a[l]=a[i] then 31 begin 32 if ans[l,j+1]-ans[l,min(j+k,m-1)+1]>0 then 33 f[i,j]:=1; 34 end else 35 begin 36 if ans[l,j+1]-ans[l,min(j+k,m-1)+1]<min(j+k,m-1)-(j+1)+1 then 37 f[i,j]:=1; 38 end; 39 ans[i,j]:=ans[i,j+1]+f[i,j]; 40 end; 41 end; 42 43 procedure print; 44 var 45 i:longint; 46 begin 47 for i:=1 to n do 48 if f[i,0]=1 then write(a[i],' ') 49 else write(a[i] xor 1,' '); 50 end; 51 52 begin 53 assign(input,'vode.in'); 54 assign(output,'vode.out'); 55 reset(input); 56 rewrite(output); 57 init; 58 main; 59 print; 60 close(input); 61 close(output); 62 end.