-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgrouped_bag.cpp
More file actions
82 lines (71 loc) · 2.03 KB
/
grouped_bag.cpp
File metadata and controls
82 lines (71 loc) · 2.03 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
分组背包(多重背包是其一种特殊情况)
有 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
3 5
2
1 2
2 4
1
3 4
1
4 5
8
*/
/*
分组背包问题:
1. 有N组物品,每组物品中只能选择一个
2. 背包容量为V
3. 求解在不超过背包容量的情况下,能获得的最大价值
算法思路:
1. 状态表示:dp[j]表示容量为j的背包能获得的最大价值
2. 状态转移:dp[j] = max(dp[j], dp[j-v[k]] + w[k]),其中k是当前组内的物品编号
3. 遍历顺序:
- 外层循环遍历物品组
- 中层循环逆序遍历背包容量(避免一个组内选多个物品)
- 内层循环遍历组内物品
时间复杂度:O(N * V * S),其中S是每组物品的平均数量
空间复杂度:O(V),使用一维滚动数组优化
*/
#include <iostream>
using namespace std;
const int N = 110;
int n, V, dp[N], v[N], w[N];
int main()
{
cin >> n >> V;
for (int i = 0; i < n; i++)
{
int s;
cin >> s;
for (int j = 1; j <= s; j++)
{
cin >> v[j] >> w[j];
}
for (int j = V; j >= 0; j--)
{
for (int k = 1; k <= s; k++)
{
if (j >= v[k])
{
dp[j] = max(dp[j], dp[j - v[k]] + w[k]);
}
}
}
}
cout << dp[V];
return 0;
}