【背包问题】刘翔!加油!

题目:刘翔!加油! rqnoj329

题目描述

刘翔因伤从北京奥运会的跑道上下来以后,十分的痛苦难过!全国人民看到后都为刘翔加油,支持和关心刘翔!因此,很多人写信来安慰他。没多久,就收到了一大堆信件,可他处理不了这么多,便找到ssxyh处理。ssxyh将信件分了n分,每份信件都有自己的,欣赏价值value,消耗时间time,消耗体力h,和得到的鼓舞w。观看信件必须按照价值递增(大于)的顺序观看,不一定需要全看,例如看了价值45之后就不能再看价值23的了。(为什么?,如果先看了小胡的信当然再看布什的信就不爽了,谁看得下去啊。。。。)可是,翔在伤病中,时间和体力都有限,分别为t,m,同时看完之后体力不能为0(会挂的。。)。这下ssxyh也犯难了,只好请求你帮忙,如何在这些条件下使刘翔获得最大的鼓舞呢??

输入格式

第一行n,m,t(n,m,t<=100)
第二行到n+1行,每行4个数,value,time,h,w

输出格式

一个数,最大的鼓舞!

样例输入

样例输出

这一题是垃圾陷阱一题深化的http://www.cnblogs.com/oijzh/archive/2012/08/19/2646103.html

转移方程不再多说,不懂的点上面的链接,只需把boolean改成longint,然后计算即可

Pascal Code

program rqnoj329;

var
  n,hp,time:longint;
  v,t,h,w:array[0..100+10] of longint;
  f:array[0..100+10,0..100+10] of longint;//(第几个,就地滚动),体力,时间,longint:鼓舞

procedure init;
begin
  assign(input,'rqnoj329.in');
  assign(output,'rqnoj329.out');
  reset(input);
  rewrite(output);
end;

procedure outit;
begin
  close(input);
  close(output);
  halt;
end;

procedure swap(var a,b:longint);
var t:longint;
begin
  t:=a;a:=b;b:=t;
end;

procedure qsort(l,r:longint);
var
  i,j,x:longint;
begin
  i:=l;j:=r;x:=v[(i+j)div 2];
  repeat
    while v[i]>x do inc(i);
    while v[j]<x do dec(j);
    if i<=j then
    begin
      swap(v[i],v[j]);
      swap(t[i],t[j]);
      swap(h[i],h[j]);
      swap(w[i],w[j]);
      inc(i); dec(j);
    end;
  until i>j;
  if i<r then qsort(i,r);
  if l<j then qsort(l,j);
end;

procedure readdata;
var
  i,j:longint;
begin
  read(n,hp,time);//信件封数,体力,时间
  for i:=1 to n do
    read(v[i],t[i],h[i],w[i]);//价值,时间,体力,鼓舞

  qsort(1,n);//按价值降序排序
  {for i:=1 to n do
    writeln(v[i],' ',t[i],' ',h[i],' ',w[i]);}

  //初始化
  for i:=0 to hp do
    for j:=0 to time do f[i,j]:=0;
end;

procedure main;
var
  i,j,k,max:longint;
begin
  //f[1,0]:=0;
  
  for i:=1 to n do
    for j:=hp downto h[i]+1 do
      for k:=time downto t[i] do
      begin
        if {(f[j-h[i],k-t[i]]<>-1)and}(f[j-h[i],k-t[i]]+w[i]>f[j,k]) then
          f[j,k]:=f[j-h[i],k-t[i]]+w[i];
      end;
      
  max:=0;
  for i:=0 to hp do
    for j:=0 to time do
      if f[i,j]>max then max:=f[i,j];
      
  writeln(max);
end;

begin
  init;
  readdata;
  main;
  outit;
end.

 

 

posted @ 2012-08-19 09:07  jiangzh  阅读(172)  评论(0)    收藏  举报