动态规划背包问题6分组背包

动态规划背包问题6分组背包

四月 11, 2020

分组背包


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

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

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

输出最大价值。

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

接下来有 N 组数据:

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

数据范围
0<N,V≤100
0<Si≤100
0<vij,wij≤100


分组背包问题
有许多组的物品,每一组物品只能选一个的01背包。
解决方法:最内层加一个遍历当前组,当前体积是j的时候,就变成取哪个物品可以使当前的dp最大。
当前重量不变,只是换了一个物品往里装,就保证只放一样物品了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.util.*;
class thing {
int v;//体积
int w;//价值
public thing (int v,int w) {
this.v = v;
this.w = w;
}
}
public class Main {

public int solve(int N,int V,ArrayList<ArrayList<thing>> list) {
int[] dp = new int[V + 1];
for (int i = 0; i < N; i++) {
ArrayList<thing> sub = list.get(i);
for (int j = V; j >= 0; j--) {
for (int k = 0; k < sub.size(); k ++) {
thing t = sub.get(k);
if (j - t.v >= 0) {
dp[j] = Math.max(dp[j],dp[j - t.v] + t.w);
}
}
}
//show(dp);
}


return dp[dp.length - 1];

}
public static void show(int[] arr) {
for (int i = 0; i <arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println("*");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Main main = new Main();
int N = sc.nextInt();
int V = sc.nextInt();
ArrayList<ArrayList<thing>> list = new ArrayList<>(N);
for (int index = 0; index < N; index ++) {
int s = sc.nextInt();
ArrayList<thing> sub = new ArrayList<>(s);
thing th = null;
for (int i = 0; i < s; i ++) {
int v = sc.nextInt();
int w = sc.nextInt();
th = new thing(v,w);
sub.add(th);
}
list.add(sub);
}

System.out.println(main.solve(N,V,list));
}
}