落谷P1156 垃圾陷阱

原题链接:https://www.luogu.com.cn/problem/P1156

P1156 垃圾陷阱

题目描述

卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中。“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2D100)英尺。

卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。

每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。

假设卡门预先知道了每个垃圾扔下的时间t(0<t1000),以及每个垃圾堆放的高度h(1h25)和吃进该垃圾能维持生命的时间f(1f30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续10小时的能量,如果卡门10小时内没有进食,卡门就将饿死。

输入格式

第一行为2个整数,D和 G(1G100),G为被投入井的垃圾的数量。

第二到第G+1行每行包括3个整数:T (0 < T <= 1000),表示垃圾被投进井中的时间F(1F30),表示该垃圾能维持卡门生命的时间;和H(1H25),该垃圾能垫高的高度。

输出格式

如果卡门可以爬出陷阱,输出一个整表示最早什么时候可以爬出;否则输出卡门最长可以存活多长时间。

输入输出样例

输入 #1
20 4
5 4 9
9 3 2
12 6 10
13 1 1
输出 #1
13

说明/提示

[样例说明]

卡门堆放她收到的第一个垃圾:height=9

卡门吃掉她收到的第2个垃圾,使她的生命从10小时延伸到13小时;

卡门堆放第3个垃圾,height=19

卡门堆放第4个垃圾,height=20

这个题是一个类似背包问题,垃圾的高度看成物重,能增加的生命的长短看成价值,把井的高度看成背包的大小,但和背包不同的是,题目要求至少将这个背包填满,需要对代码进行以下修改

开一个结构体(记录)a[i].t,a[i].f,a[i].h分别代表第i个物体的投入时间,持续生命时间和高度。

设b[j]表示到达高度j时所拥有的最长的生命时间,注意b[0]=10。

那么转态转移应该是if(b[j]>b[j+a[i].h])b[j+a[i].h]=b[j];

如果有一个j+a[i].h>=d,那么就代表走出去了,

如果循环完了还没走出去就应该输出最长存活的时间。

下面是代码:

c/c++:

#include<stdio.h>
struct sj{
int t,f,h; 
}a[1001];
int b[1001];
int d,g;
void px(int k,int s){
    int i,j,mid;
    struct sj p;
    i=k;j=s;
    mid=a[(k+s)/2].t;
    do{
        while(a[i].t<mid)i++;
        while(a[j].t>mid)j--;
        if(i<=j){
            p=a[i];
            a[i]=a[j];
            a[j]=p;
            i++;j--;}
    }while(i<=j);
    if(i<s)px(i,s);
    if(k<j)px(k,j);
}
int main(){
    scanf("%d%d",&d,&g);
    for(int i=1;i<=g;i++)scanf("%d%d%d",&a[i].t,&a[i].f,&a[i].h);
    px(1,g);
    b[0]=10;
    for(int i=1;i<=g;i++)for(int j=d;j>=0;j--)
        if(b[j]>=a[i].t){
            if(j+a[i].h>=d){printf("%d",a[i].t);return 0;};
            if(b[j]>b[j+a[i].h])b[j+a[i].h]=b[j];
            b[j]+=a[i].f;
        }
    printf("%d",b[0]);
    return 0;
}

pascal:

type sj=record
    t:integer;
    f:integer;
    h:integer;
end;
var
    a:array[0..1000]of sj;
    b:array[0..1000]of integer;
    d:integer;
    g:integer;
procedure px(k,s:integer);
var
    i:integer;
    j:integer;
    mid:integer;
    p:sj;
begin
    i:=k;j:=s;
    mid:=a[(k+s) div 2 ].t;
    while i<=j do begin
        while a[i].t<mid do i:=i+1;
        while a[j].t>mid do j:=j-1;
        if i<=j then begin
            p:=a[i];
            a[i]:=a[j];
            a[j]:=p;
            i:=i+1;
            j:=j-1;
        end;
    end;
    if i<s then px(i,s);
    if k<j then px(k,j);
end;
var
    i:integer;
    j:integer;
begin
    readln(d,g);
    for i:=1 to g do readln(a[i].t,a[i].f,a[i].h);
    px(1,g);
    b[0]:=10;
    for i:=1 to g do for j:=d downto 0 do 
        if b[j]>=a[i].t then begin
            if j+a[i].h>=d then begin
                writeln(a[i].t);exit();
            end;
            if b[j]>b[j+a[i].h] then b[j+a[i].h]:=b[j];
            b[j]:=b[j]+a[i].f;
        end;
    writeln(b[0]);
end.

猜你喜欢

转载自www.cnblogs.com/sy666/p/12358885.html