zoukankan      html  css  js  c++  java
  • JZOJ_1322. 硬币游戏 (Standard IO)

    Description

      FJ的奶牛喜欢玩硬币游戏,所以FJ发明了一个新的硬币游戏。一开始有N(5<=N<=2,000)个硬币堆成一叠,从上往下数第i个硬币有一个整数值C_i(1<=C_i<=100,000)。
      两个玩家轮流从上倒下取硬币,玩家1先取,可以从上面取1个或2个硬币,下一轮的玩家可以取的硬币数量最少为1个,最多为上一个玩家取的数量的2倍,硬币全部取完比赛结束。
      已知玩家2绝顶聪明,会采用最优策略,现在请你帮助玩家1,使得玩家1取得的硬币值的和最大。
     

    Input

      第一行输入N
      第二至N+1行每行输入一个整数C_i
     

    Output

      输出玩家1能获得的最大值。
     

    Solution

    Fi,j,i表示的是我现在的位置(还剩多少枚硬币),取到第几个,j是对方上一次对方拿走了多少个。

    下一次对手就可以取走2*j枚硬币,我们设他要拿走k枚硬币,那么k的取值范围就在1<k<=2∗j。

    fi,j=max(sumi+1..k−fk,k−i(1<=k<=2∗j))

    fi,j+1=max(sumi+1..k−fk,k−i(1<=k<=2*(j+1)))

    J就只有在这个地方发生了改变(手指上方S)

    (1<=k<=2∗j) 和 (1<=k<=2*(j+1)) 可以变为 2*j<=k<=2*(j+1)

    Fi,j=max(Fi,j−1,Sumi+1..k−Fk,k−i(2∗(j−1)<k<=2∗j))

    Fi,j;=max(Fi,j-1,Sumi+1..k-Fk,k-i) (2j+1<=k<=2j+2) (Sum为前缀和)

    Maxn;=max(Maxn,Sum[k]-Sum[i]-F[k,k-i])

    答案即为 (sum[n]+max(num[1]-f[1,1],num[1]+num[2]-f[2,2])) div 2

    因为一开始可以选1或者2

    复杂度;O(n2) (2算是常数)

    代码

     1 var
     2   n:longint;
     3   a,sum:array [0..2001] of longint;
     4   f:array [0..2001,0..2001] of longint;
     5 procedure init;
     6 var
     7   i:longint;
     8 begin
     9   readln(n);
    10   sum[0]:=0;
    11   for i:=1 to n do
    12     begin
    13       readln(a[i]);
    14       sum[i]:=sum[i-1]+a[i];
    15     end;
    16 end;
    17 
    18 function min(o,p:longint):longint;
    19 begin
    20   if o<p then exit(o);
    21   exit(p);
    22 end;
    23 
    24 function max(o,p:longint):longint;
    25 begin
    26   if o>p then exit(o);
    27   exit(p);
    28 end;
    29 
    30 procedure main;
    31 var
    32   i,j,k,maxx:longint;
    33 begin
    34   for i:=n-1 downto 1 do
    35     begin
    36       maxx:=-maxlongint;
    37       for j:=1 to i do
    38         begin
    39           for k:=min(i+2*j-2,n)+1 to min(i+2*j,n) do
    40             maxx:=max(maxx,sum[k]-sum[i]-f[k,k-i]);
    41           f[i,j]:=maxx;
    42         end;
    43     end;
    44   writeln((sum[n]+max(a[1]-f[1,1],a[1]+a[2]-f[2,2])) div 2);
    45 end;
    46 
    47 begin
    48   init;
    49   if n=1 then writeln(a[1])
    50          else main;
    51 end.
  • 相关阅读:
    JS站点
    1011 World Cup Betting (20分)
    1007 Maximum Subsequence Sum (25分)(动态规划DP)
    1006 Sign In and Sign Out (25分)
    1005 Spell It Right (20分)
    1004 Counting Leaves (30分)(DFS)
    1003 Emergency (25分)(Dijkstra算法)
    1002 A+B for Polynomials (25分)
    1001 A+B Format (20分)
    canvas
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9489350.html
Copyright © 2011-2022 走看看