多重背包问题I

题目

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

第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。

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

输入格式:

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

接下来有 N 行,每行三个整数 vi,wi,si 用空格隔开,分别表示第 i 种物品的体积、价值和数量。

输出格式:

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

数据范围:

0<N,V≤1000<N,V≤100
0<vi,wi,si≤100

代码

import java.util.Scanner;

public class _多重背包问题I {

    public static void main(String[] args) {
        Scanner scanner =new Scanner(System.in);
        int N =scanner.nextInt();
        int V=scanner.nextInt();

        int[] dp=new int[V+1];
        for (int i = 0; i < N; i++) {
            int v=scanner.nextInt();
            int w=scanner.nextInt();
            int s=scanner.nextInt();

            for(int j=V;j>=0;j--){
                for(int k=1;k<=s&&k*v<=j;k++){
                    dp[j]=Math.max(dp[j],dp[j-k*v]+k*w);
                }
            }
        }
        System.out.println(dp[V]);
        scanner.close();
    }
}

详解

  1. public static void main(String[] args) {
    • 这是程序的主入口点。当你运行程序时,它将从这里开始执行。

2-3. Scanner scanner = new Scanner(System.in);

  • 创建一个Scanner对象,用于从标准输入(通常是键盘)读取数据。

4-5. int N = scanner.nextInt();

  • 读取一个整数N,它表示有多少种不同的物品。

6-7. int V = scanner.nextInt();

  • 读取一个整数V,它表示背包的总容量。
  1. int[] dp = new int[V + 1];
    • 创建一个整数数组dp,其长度为V + 1。这个数组将用于存储对于每个可能的背包容量(从0到V),能够获得的最大价值。

11-17. for (int i = 0; i < N; i++) {

  • 开始一个循环,遍历每种物品。

12-13. int v = scanner.nextInt();

  • 读取当前物品的重量。

14-15. int w = scanner.nextInt();

  • 读取当前物品的价值。
  1. int s = scanner.nextInt();
  • 读取当前物品的数量限制。

18-25. for (int j = V; j >= 0; j--) {

  • 开始一个内循环,从背包的最大容量V遍历到0。

19-22. for (int k = 1; k <= s && k * v <= j; k++) {

  • 这是多重背包问题的核心。这个循环允许你选择0到s个当前物品,但不超过背包的当前容量j
  1. dp[j] = Math.max(dp[j], dp[j - k * v] + k * w);
  • 更新dp数组。这一行代码的意思是,对于当前的背包容量j,比较两个选项:不放入任何新的当前物品(保持dp[j]不变)和放入k个当前物品(dp[j - k * v] + k * w)。选择两者中的较大值作为新的dp[j]
  1. }
  • 内循环结束。
  1. }
  • 外循环结束。
  1. System.out.println(dp[V]);
  • 输出dp[V],即当背包容量为V时能够获得的最大价值。
  1. scanner.close();
  • 关闭scanner对象,释放与其相关的资源。
  1. }
  • 主函数结束。

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值