【12普及模拟】采药

问题描述
凡凡是个聪明的孩子,今天他也要去采药,但是这次和聪聪不一样,他采的药是密度很大的,所以不仅要求背包的总空间V能放得下所采的药,还要求药草的总质量不能超过凡凡所能承受的范围M。
由于凡凡运动力惊人并且拥有敏锐的察觉力,所以他能发现N种珍惜的药材,对于每个药材凡凡都会精准地目测出其质量、体积和价值,现在要你做出一些取舍,使凡凡所能采到的药材的总价值最大。
注意:每种药材只有一个。
输入
第一行有三个整数M、V、N。
接下来有N行,每行三个整数,分别表示一种药材的质量、体积、价值。
输出
一行一个数,表示能获得的最大价值。
样例输入
10 20 4
4 8 90
3 16 60
6 12 10
6 3 40
样例输出
130
数据范围
对于30%的数据,所有的药草的质量为1。
对于100%的数据,M,V<=300,N<=100,对于每一种药草,它的质量、体积分别小于M和V,它的价值小于2^30。最后的总价值可能很大,但不超过2^63。
算法讨论
第一题居然要dp←_←,由于每种药只有一个,就是个01背包,每种药只有取与不取两种,f[i,j]表示背包内用了i个体积,j个重量的最大价值,倒推即可。
状态转移方程:f[i,j]:=max(f[i,j],f[i-v[k],j-m[k]]+p[k]) (v[k]<=i<=v1;m[k]<=j<=m1;1<=k<=n)

const
  maxn=100;
  maxm=300;
var
  a:array[-maxm..maxm,-maxm..maxm] of int64;
  m,v,p:array[1..maxn] of longint;
  i,j,k,n,m1,v1:longint;

function max(x,y:int64):int64;
begin
  if x>y
    then exit(x)
    else exit(y)
end;

begin
  assign(input,'medic.in'); reset(input);
  assign(output,'medic.out'); rewrite(output);
  read(m1,v1,n);
  for i:=1 to n do
    read(m[i],v[i],p[i]);
  for i:=1 to n do
    for j:=v1 downto v[i] do
      for k:=m1 downto m[i] do
        a[j,k]:=max(a[j,k],a[j-v[i],k-m[i]]+p[i]);
  write(a[v1,m1]);
  close(input); close(output)
end.

这里写图片描述
Pixiv ID:62375267

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值