太空梯

题目描述

很久以前,魔法世界的人们注重于眼前的享乐,失去了探索宇宙,探索未知世界的兴趣,他们经常以急功近利的心态评价一件事:“这对我有什么用呢?”幸好当时的领导人远见卓识,他说:“我们历史上曾经因错失大航海时代,而导致了长达数百年的衰落。今天,我们不能再错失太空时代,我们的征途将是星辰大海!”所以现在魔法学院才能够有足够的技术实力建造太空梯(用魔法石垒)进入太空以应对天顶星人的威胁。他们有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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值