关闭

剪草

标签: 编程
165人阅读 评论(0) 收藏 举报

【题目描述】
有N棵小草,编号0至N-1。奶牛Bessie不喜欢小草,所以Bessie要用剪刀剪草,目标是使得这N棵小草的高度总和不超过H。在第0时刻,第i棵小草的高度是h[i],接下来的每个整数时刻,会发生如下三个步骤:
(1)每棵小草都长高了,第i棵小草长高的高度是grow[i]。
(2)Bessie选择其中有一棵小草并把它剪平,这棵小草高度变为0。注意:这棵小草并没有死掉,它下一秒还会生长的。
(3)Bessie计算一下这N个小草的高度总和,如果不超过H,则完成任务,一切结束,否则轮到下一时刻。
你的任务是计算:最早是第几时刻,奶牛Bessie能完成它的任务?如果第0时刻就可以完成就输出0,如果永远不可能完成,输出-1,否则输出一个最早的完成时刻。
【输入格式】
第一行,两个整数N和H。 1 <= N <= 50,0 <= H <= 1000000。
第二行,N个整数,表示h[i]。0 <= h[i] <= 100000。
第三行,N个整数,表示grow[i]。1 <= grow[i] <= 100000。
【输出格式】
一个整数,最早完成时刻或-1。
【样例输入】
7 33
5 1 6 5 8 4 7
2 1 1 1 4 3 2
【样例输出】
5
【样例解释】
第1秒剪第2棵小草,第2秒剪第0棵小草,第3秒剪6棵小草,第4秒剪第5棵小草,第5秒剪第4棵小草。
【分析】
动态规划,设F[i,j]表示在前i棵草中割j刀的最优解。先以生长速度为关键字排序消除后效性,再用动态规划求解。

uses math;
var
  i,j,k,n,high:longint;
    h,g:array[-1..51]of longint;
    f:array[-1..51,-1..51]of longint;
procedure qsort(l,r:longint);
var
  i,j,temp,mid:longint;
begin
  i:=l; j:=r;
  mid:=g[(l+r) div 2];
  repeat
    while g[i]<mid do inc(i);
    while g[j]>mid do dec(j);
    if i<=j then
    begin
      temp:=g[i];g[i]:=g[j];g[j]:=temp;
            temp:=h[i];h[i]:=h[j];h[j]:=temp;
      inc(i);dec(j);
    end;
  until i>j;
  if l<j then qsort(l,j);
  if i<r then qsort(i,r);
end;
begin
  readln(n,high);
    if high=0 then begin write(-1);exit; end;
    for i:=1 to n do read(h[i]);
    for i:=1 to n do read(g[i]);
    qsort(1,n);
    for i:=0 to n do begin
      for j:=1 to n do f[j,0]:=f[j-1,0]+h[j]+g[j]*i;
        for j:=1 to n do
          for k:=1 to i do
              f[j,k]:=min(f[j-1,k-1]+g[j]*(i-k),f[j-1,k]+h[j]+g[j]*i);
        if f[n,i]<=high then begin write(i);exit; end;
    end;
    write(-1);
end.
3
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:47515次
    • 积分:2479
    • 等级:
    • 排名:第14875名
    • 原创:165篇
    • 转载:21篇
    • 译文:0篇
    • 评论:12条
    博客专栏