您的位置:首页 > 其它

取数游戏 纪中 1308 蜜汁dp

2016-07-14 07:54 711 查看

Description

  Alice想让Bob陪他去看《唐山大地震》,但由于Bob是个很感性的人,怕流泪不想去,但又不好意思以这个作为拒绝的理由,便提出玩一个游戏。

  N个正整数围成一圈,规则如下:

  •两个玩家轮流取数;

  •最开始先手的玩家可以取任意一个数x;

  •从第二步开始当前玩家只能取x(上一玩家刚刚取的数)左右两边相邻的数;

  •直到取完所有的数,游戏结束;

  •取得较多奇数的玩家获胜。

  Bob为了显示大度,让Alice先取,但他忘了自己和Alice都是绝顶聪明之人,现在Alice请你帮他计算第一步有多少种取法使得最终获得胜利。

Input

  第一行包含一个整数N(1<=N<=100),表示数的个数。第二行包含N个正整数,每个数都在1到1000之间,任意两个数互不相同。

Output

  输出Alice第一步有多少种取法。

 

分析

这个东西有一些玄。

首先我们设一个s[i,j]表示i—j区间中奇数的个数。

f[i,j]=max(s[i,j]−f[i+1,j],s[i,j]−f[i,j−1])

可以枚举Alice的第一次选择。

自行画图理解。

代码

va-r
a:array[0..200] of longint;
s:array[0..200] of longint;
f:array[0..200,0..200] of longint;
i,j,k,l:longint;
ans:longint;
n:longint;

function max(x,y:longint):longint;
begin
if x>y then max:=x
else max:=y;
end;

begin
readln(n);
for i:=1 to n do
read(a[i]);
for i:=1 to n do
begin
k:=0;
fillchar(f,sizeof(f),0);
fillchar(s,sizeof(s),0);
for j:=1 to n do
begin
k:=k+1;
if a[j] mod 2=1
then
begin
//k:=k+1;
f[k,k]:=1;
end;
end;
for j:=1 to n do
begin
s[j]:=s[j-1];
if a[j] mod 2=1
then s[j]:=s[j]+1;
end;
for k:=1 to n-2 do
for j:=1 to n-k do
begin
l:=k+j;
f[j,l]:=max(s[l]-s[j-1]-f[j+1,l],s[l]-s[j-1]-f[j,l-1]);
l:=l;
end;
f[1,n]:=s[l]-f[2,n];
if s
div 2+1<=f[1,n] then ans:=ans+1;
k:=a[1];
for j:=1 to n do
a[j]:=a[j+1];
a
:=k;
end;
write(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: