多重背包问题

题目描述:

有N种物品,每种物品的数量为C1,C2......Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的最大价值。

输入

第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。
第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。

输出

输出可以容纳的最大价值。

与零一背包不同的是,零一背包中的物品是不可以重复拿取的,只可以拿取当前物品或者不拿取当前物品,不可以拿取多个,完全背包的物品是可以任意拿取多个的来构成不超过背包容量并且构成的总价值是最大的.

而这道题是多重背包问题,也就是这个物品的个数是有限个的,在物品个数范围内可以任意选择

动态规划的核心是找到dp公式或者状态转移的方程,理解清楚中间的过程是怎么样进行变化的,因为动态规划总是要利用到之前上一个物品选择后的最佳方案,所以dp数组里面存储的肯定是历史上存储的最佳方案。

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6         Scanner input = new Scanner(System.in);
 7             
 8         int N = input.nextInt();// 输入物品个数
 9         int V = input.nextInt();// 输入背包容量数
10         
11         int[] v = new int[N+1];// 物品的体积数组
12         int[] w = new int[N+1];// 物品的价值数组
13         
14         int[][] f = new int[N+1][V+1];// 备忘录
15         
16         // 循环输入物品的体积和价值
17         for (int i = 1; i <= N; i++) {
18             v[i] = input.nextInt();
19             w[i] = input.nextInt();
20         }
21         
22         for (int i = 1; i <= N; i++) { // 现在考虑第i个物品
23             for (int j = 0; j <= V; j++ ) {// 背包容量从0开始
24                 f[i][j] = f[i-1][j];
25                 if (j >= v[i]) {
26                     f[i][j] = Math.max(f[i][j], f[i-1][j-v[i]] + w[i]);
27                 }         
28             }           
29         }
30         
31         int max = 0;
32         for (int i = 0; i <= V; i++) {
33             max = Math.max(max, f[N][i]);
34         }
35         System.out.println(max);
36 
37     }
38 
39 }

 

posted @ 2021-03-25 08:27  YTTY  阅读(76)  评论(0)    收藏  举报