Monster (贪心)

内容目录

Monster

【题目描述】

明明的手机上有这样一个游戏,有一排n个怪物,每个怪物的血量是mi。现在明明可以射出k个伤害均为p的火球射向某些怪物。当某个火球射到第i个怪物,除了这个怪物会掉血p以外,它左边的第j个怪物(j<=i),也会遭到Max(0, p - (i - j)* (i - j))的溅射伤害。当某个怪物的血量为负的时候,它就死了,但它的尸体已然存在,即其他怪物不会因为它死而改变位置。

明明想用这k 个火球消灭掉所有的怪物,但他同时希望每个火球的伤害p能尽可能的小,这样他才能完美过关。

【输入数据】

第一行两个数 nk (1≤ n ≤ 50000, 1 ≤ k ≤ 100000)。

第二行n个数m1m2,...mn (1 ≤ mi ≤ 109),表示每个怪物的生命值。

【输出数据】

最小的符合要求的p值。

【样例输入】

3 1

1 4 5

【样例输出】

6

【数据范围】

1 ≤ n ≤ 50000, 1 ≤ k ≤100000,1 ≤ mi ≤109

30%的数据,n ≤ 500

贪心+二分 显然 最右边那个妖怪一定是被轰击致死的

Program monster;
const
   INF=1000000000;
var
  n,k,i,j:longint;
  m1,a:array[1..50000] of longint;
procedure sort(l,r:longint);
var
   i,j,m,k2,kn:longint;
begin
   if l=r then
   begin
      writeln(l);
      close(input);
      close(output);
      halt;

   end;

   m:=(l+r) shr 1;
   for i:=1 to n do a[i]:=m1[i];
   k2:=k;
   for i:=n downto 1 do
      if a[i]>0 then
      begin
         kn:=k2;
         dec(k2,a[i] div m);
         a[i]:=a[i] mod m;
         if a[i]>0 then
         begin
            dec(k2);
            dec(a[i],m);
         end;

         if k2<0 then sort(m+1,r);
         kn:=kn-k2;
         j:=i-1;
         while (m-sqr(i-j)>0) and (j>=1) do
         begin
            if (kn*(a[j]-m+sqr(i-j))<0) then a[j]:=0 else
            dec(a[j],kn*(m-sqr(i-j)));
            dec(j);
         end;

      end;
   sort(l,m);


end;
begin
   assign(input,'monster.in');
   assign(output,'monster.out');
   reset(input);
   rewrite(output);

   read(n,k);
   for i:=1 to n do
   begin
      read(m1[i]);
      inc(m1[i]);
   end;


   sort(1,inf+1);


end.