侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 675 篇文章
  • 累计创建 128 个标签
  • 累计收到 28 条评论

目 录CONTENT

文章目录

【动态规划】二维费用的背包问题

GabrielxD
2023-02-15 / 0 评论 / 0 点赞 / 399 阅读 / 706 字
温馨提示:
本文最后更新于 2023-02-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

8. 二维费用的背包问题 - AcWing题库


NN 件物品和一个容量是 VV 的背包,背包能承受的最大重量是 MM

每件物品只能用一次。体积是 viv_i ,重量是 mim_i ,价值是 wiw_i

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

输入格式

第一行三个整数, N,V,MN,V, M ,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。

接下来有 NN 行,每行三个整数 vi,mi,wiv_i, m_i, w_i ,用空格隔开,分别表示第 ii 件物品的体积、重量和价值。

输出格式

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

数据范围

0<N10000 \lt N \le 1000
0<V,M1000 \lt V, M \le 100
0<vi,mi1000 \lt v_i, m_i \le 100
0<wi10000 \lt w_i \le 1000

输入样例

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

输出样例:

8

解题

方法一:动态规划

思路

思维过程:

image-20230216073031144

动态规划:

  • 状态定义:f[i][j][k]f[i][j][k] 表示所有只考虑ii 个物品,总体积不大于 jj 且总重量不大于 kk 的所有选法中能得到的最大价值

  • 状态转移方程:f[i][j][k]=max{f[i1][j][k]f[i1][jv[i]][km[i]]+w[i]v[i]jV,m[i]kMf[i][j][k] = \max \begin{cases} f[i-1][j][k] \\ f[i-1][j-v[i]][k-m[i]] + w[i] & v[i] \le j \le V, m[i] \le k \le M \end{cases}

  • 初始状态:只考虑前 00 个物品的时候没有物品可选,最大价值一定是 00

代码

import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        in.nextToken();
        int N = (int) in.nval;
        in.nextToken();
        int V = (int) in.nval;
        in.nextToken();
        int M = (int) in.nval;
        int[][] f = new int[V + 1][M + 1];
        for (int i = 0; i < N; ++i) {
            in.nextToken();
            int v = (int) in.nval;
            in.nextToken();
            int m = (int) in.nval;
            in.nextToken();
            int w = (int) in.nval;
            for (int j = V; j >= v; --j) {
                for (int k = M; k >= m; --k) {
                    f[j][k] = Math.max(f[j][k], f[j - v][k - m] + w);
                }
            }
        }
        System.out.println(f[V][M]);
    }
}
0

评论区