动态规划-分组背包问题

  1. 问题描述

有N件物品和一个容量是V的背包,每组物品有若干个,同一组内的物品最多只能选一个,每件物品的体积是vij,价值是wij,求解将哪些物品装入背包可以使物品的总体积不超过背包容量,且总价值最大,输出最大价值。

  1. 输入格式及输出格式

输入格式:第一行两个整数,表示物品数量和背包容积,接下来有N行,每组数据第一行有一个整数si,表示第i个组的物品数量,接下来si行,每行有两个整数vij和wij,表示第i个物品组的第j个物品的体积和价值。

输出格式:输出一个整数,表示最大价值

  1. 基本思想

这题在01背包的问题上,新增了组的限制,所以只需要加一层循环用于在组中选取数据即可,优化思维和01背包问题一致。关于从前遍历还是从后遍历是大家比较关注的一个点,其实只需要记住:当前数组是要用到前一层的数据,则从后往前,反之从前往后。

  1. 代码实现

由上述分析,可得代码如下

#include <iostream>

using namespace std;

const int N = 110;
int n, m;
int v[N][N], w[N][N], s[N], f[N];

int main(){
    
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++ ) {
        cin >> s[i];
        for (int j = 0; j < s[i]; j ++ )
            cin >> v[i][j] >> w[i][j];
    }
    
    for (int i = 1; i <= n; i ++ )
        for (int j = m; j >= 0; j -- )
            for (int k = 0; k < s[i]; k ++ )
                if (v[i][k] <= j)
                    f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
    
    cout << f[m] << endl;
    
    return 0;
}

任何错误,欢迎指正,Thanks♪(・ω・)ノ

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值