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.
  • 相关阅读:
    Linux动态链接(4)ldd与ldconfig
    Linux动态链接(3)so文件映射地址
    Linux动态链接(2)so初始化执行
    Linux动态链接(1)惰性链接
    kill信号由谁接收处理
    gdb调试器之"测不准原则"
    gdb动态库延迟断点及线程/进程创建相关事件处理(下)
    gdb动态库延迟断点及线程/进程创建相关事件处理(上)
    Redis集群,备份,哨兵机制
    hyper-v虚拟机centos7网络配置
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9489350.html
Copyright © 2011-2022 走看看