多重背包.

题目描述
给有一个能承重 V 的背包,和n种物品,每种物品的数量有限多,我们用重量、价值和数量的三元组来表示一个物品,第 i 件物品表示为(Vi,Wi,Si),问在背包不超重的情况下,得到物品的最大价值是多少?

54E9C51263E1462585A8F6595841EEC0.jpg

输入
第一行输入两个数V、n,分别代表背包的最大承重和物品种类数。

接下来 n 行,每行三个数 Vi、Wi、Si,分别代表第 i 种物品的重量、价值和数量。

输出
输出一个整数,代表在背包不超重情况下所装物品的最大价值。

样例输入1

15 4
4 10 5
3 7 4
12 12 2
9 8 7

样例输出1

37

数据规模与约定
时间限制:1 s

内存限制:64 M

60% 的数据保证(Vi≤V≤1000,n≤100,Si≤10,Wi≤1000)​
100% 的数据保证(Vi≤V≤100000,n≤100,Si≤100000,Wi≤1000)

#include <iostream>
using namespace std;

int all, n, ind, w[100005], v[100005], ans[100000];

int main() {
    cin >> all >> n;
    for (int i = 0; i < n; i++) {
        int x, y, z;
        cin >> x >> y >> z;
        for (int j = 0; j < z; j++) {
            ind++;
            w[ind] = x;
            v[ind] = y;
        }
    }
    for (int i = 1; i <= ind; i++) {
        for (int j = all; j >= w[i]; j--) {
            ans[j] = max(ans[j], ans[j - w[i]] + v[i]);
        }
    }
    cout << ans[all] << endl;
    return 0;
}
 

二进制优化

#include <iostream>
using namespace std;

int all, n, ind, w[100005], v[100005], ans[100005];
int t[20];

int main() {
    int tt = 1;
    for (int i = 0; i < 20; i++) {
        t[i] = tt;
        tt *= 2;
    }
    cin >> all >> n;
    for (int i = 0; i < n; i++) {
        int x, y, z, temp = 0;
        cin >> x >> y >> z;
        while (z > 0) {
            ind++;
            if (z >= t[temp]) {
                w[ind] = x * t[temp];
                v[ind] = y * t[temp];
                z -= t[temp];
            } else {
                w[ind] = x * z;
                v[ind] = y * z;
                z = 0;
            }
            temp++;
        }
    }
    for (int i = 1; i <= ind; i++) {
        for (int j = all; j >= w[i]; j--) {
            ans[j] = max(ans[j], ans[j - w[i]] + v[i]);
        }
    }
    cout << ans[all] << endl;
    return 0;
}
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yitahutu79

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值