原题链接:https://www.luogu.com.cn/problem/P1156
这个题是一个类似背包问题,垃圾的高度看成物重,能增加的生命的长短看成价值,把井的高度看成背包的大小,但和背包不同的是,题目要求至少将这个背包填满,需要对代码进行以下修改
开一个结构体(记录)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:
#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.
如果有什么问题,请指出,谢谢。