• acwing9. 分组背包问题


    有 N 组物品和一个容量是 V 的背包。

    每组物品有若干个,同一组内的物品最多只能选一个。
    每件物品的体积是 vij,价值是 wij,其中 i 是组号,j 是组内编号。

    求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

    输出最大价值。

    输入格式

    第一行有两个整数 N,V,用空格隔开,分别表示物品组数和背包容量。

    接下来有 NN 组数据:

    • 每组数据第一行有一个整数 Si,表示第 i 个物品组的物品数量;
    • 每组数据接下来有 Si 行,每行有两个整数 vij,wij,用空格隔开,分别表示第 i 个物品组的第 j 个物品的体积和价值;

    输出格式

    输出一个整数,表示最大价值。

    数据范围

    0<N,V≤100
    0<Si≤100
    0<vij,wij≤100

    输入样例

    3 5
    2
    1 2
    2 4
    1
    3 4
    1
    4 5
    

    输出样例:

    8
    

    方法一:

    基础课的背包到这里就结束了,只能说对状态的描述有点意会了。直接上状态转移公式

    f(i, j) = max(f(i-1, j), f(i-1, j-v1)+w1, ... , f(i-1, j-vs)+ws)

    f(i, j)表示前 i 组,给定容量 j 的最优解

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 110;
    int n, v, f[N], a[N], b[N];
    
    // f(i, j) = max(f(i-1, j), f(i-1, j-v1)+w1, ... , f(i-1, j-vs)+ws)
    
    int main() {
        int z;
        scanf("%d%d", &n ,&v);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &z);
            for (int j = 1; j <= z; ++j) {
                scanf("%d%d", &a[j], &b[j]);
            }
            for (int j = v; j >= 1; --j) {
                for (int k = 1; k <= z; ++k) {
                    if (j >= a[k])
                        f[j] = max(f[j], b[k] + f[j - a[k]]);
                }
            }
        }
    
        printf("%d", f[v]);
    }
    
  • 相关阅读:
    联赛模拟测试19
    联考Day5
    联赛模拟测试18(A.施工未补)
    题解 CF960G 【Bandit Blues】
    题解 P5518 【[MtOI2019]幽灵乐团 / 莫比乌斯反演基础练习题】
    概率与数学期望笔记
    题解 P3704 【[SDOI2017]数字表格】
    主定理
    【题解】Hikari与组合数
    【题解】P2303 [SDOI2012] Longge 的问题
  • 原文地址:https://www.cnblogs.com/nosae/p/16004988.html
Copyright © 2020-2023  润新知