[附中OJ 1772] 0/1背包问题之2

时间限制: 1 Sec 内存限制: 128 MB

题目描述
有n个重量和价值分别为wi,vi的物品。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和最大值。

输入
输入的第一行为一个整数n;第二行到第n+1行,每行两个整数,第i+1分别表示第i个物品重量wi与价值vi;最后一行有一个整数W,表示挑选出的物品总重量限制。

输出
输出只有一个整数,为所求的最大总价值。

样例输入

4
2 3
1 2
3 4
2 2
5

样例输出

7

限制条件:

1  ≤  n  ≤  100

1  ≤  w[i]≤  10^7

1  ≤  v[i]≤  100

1  ≤  W  ≤  10^9

题解:
由于w[i]过大,我们不能用正常的DP方程来求解。因为v[i]很小,我的想法是设计这样一个方程f[i]表示拿到价值为i的物品所需要的最小重量是多少,那么只需要对所有的f[i]判断是否超过W就好了。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#define LiangJiaJun main
#define INF 1999122700
using namespace std;
int w[104],v[104];
int f[50004],n,limit,z;

int LiangJiaJun(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&v[i]),z+=v[i];
    scanf("%d",&limit);
    for(int i=1;i<=50000;i++)f[i]=INF;
    f[0]=0;
    for(int i=1;i<=n;i++){
        for(int j=z;j>=v[i];j--){
            f[j]=min(f[j],f[j-v[i]]+w[i]);
        }
    }
    for(int i=z;i>=0;i--)if(f[i]<=limit) return cout<<i<<endl,0;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值