题目描述
很久以前,魔法世界的人们注重于眼前的享乐,失去了探索宇宙,探索未知世界的兴趣,他们经常以急功近利的心态评价一件事:“这对我有什么用呢?”幸好当时的领导人远见卓识,他说:“我们历史上曾经因错失大航海时代,而导致了长达数百年的衰落。今天,我们不能再错失太空时代,我们的征途将是星辰大海!”所以现在魔法学院才能够有足够的技术实力建造太空梯(用魔法石垒)进入太空以应对天顶星人的威胁。他们有k (1 ≤K ≤ 400)种不同类型的魔法石,每一种魔法石的高度为h(1 ≤ h≤100),数量为c (1 ≤ c ≤10),由于会受到太空辐射而失去魔力,每一种魔法石不能超过这种魔法石的最大建造高度a (1≤ a≤40000),试求利用这些魔法石所能修建的太空梯的最高高度。
输入
第一行为一个整数即k。第2行到第k+1行每一行有三个数,代表每种类型魔法石的特征,即高度h,限制高度a和数量c。
输出
一个整数,即修建太空梯的最大高度。
样例输入
3
7 40 3
5 23 8
2 52 6
样例输出
48
#include <bits/stdc++.h>
using namespace std;
struct data {
int h,a,c;
} d[4005];
int f[400005],i,j,k,m,ans;
bool cmp(data A,data B) {
return A.a<B.a;
}
int main() {
while (~scanf("%d",&k)&&k>0) {
memset(f,0,sizeof(f));
ans=0;
for (i=1; i<=k; ++i) scanf("%d%d%d",&d[i].h,&d[i].a,&d[i].c);
sort(d+1,d+k+1,cmp);
for (i=1; i<=k; ++i) {
if (d[i].a<d[i].h) continue;
while (d[i].c--) {
for (j=d[i].a; j>=0; --j) {if (f[j-d[i].h]+d[i].h<=j) f[j]=max(f[j],f[j-d[i].h]+d[i].h);ans=max(ans,f[j]);}
}
}
printf("%d\n",ans);
}
return 0;
}
不得不说的神级测试用例
3
5 10 1
5 20 1
10 10 1
更简单的pascal
var
h,a,c:array[1..400] of longint;
f:array[0..40000] of boolean;
i,j,k,n:longint;
procedure sort(l,r:longint);
var
i,j,x,y:longint;
begin
i:= l;
j:= r;
x:= a[(i+j)shr 1];
repeat
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if i<=j then
begin
y:= a[i]; a[i]:= a[j]; a[j]:= y;
y:= h[i]; h[i]:= h[j]; h[j]:= y;
y:= c[i]; c[i]:= c[j]; c[j]:= y;
inc(i); dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
begin
readln(n);
for i:= 1 to n do
readln(h[i],a[i],c[i]);
sort(1,n);
fillchar(f,sizeof(f),false);
f[0]:= true;
for i:= 1 to n do
for j:= 1 to c[i] do
for k:= a[i] downto h[i] do
if f[k-h[i]] then f[k]:= true;
for i:= 40000 downto 1 do
if f[i] then
begin
writeln(i);
halt;
end;
writeln(0);
end.