题目描述:
你是一名背包旅行者,准备出发去远足旅行。你有一个背包,其承重能力为 W
。你还带着 n
个物品,每个物品的重量为 w[i]
,价值为 v[i]
。每个物品只能选择放入背包或者不放入背包,即每个物品最多只能选择一次。这些物品的总价值和总重量是你需要考虑的因素。你希望在不超过背包承重能力的前提下,最大化背包中物品的总价值。
输入:
- 第一行包含两个整数
W
和n
,分别表示背包的承重能力和物品的数量。 - 接下来的
n
行,每行包含两个整数w[i]
和v[i]
,分别表示第i
个物品的重量和价值。
输出:
- 输出一个整数,表示在背包容量不超过
W
的情况下,物品的最大总价值。
示例:
输入:
5 4
1 1
2 2
3 3
4 4
输出:
1 2
说明:
在上述示例中,你可以选择放入重量为 1 和 2 的两个物品,这样背包中的总重量是 3,总价值是 1 + 2 = 3。
程序:
#include<bits/stdc++.h>
using namespace std;
int a[1001][3],dp[1001][10001];
int main(){
int w,n;
cin>>w>>n;
for(int i=0;i<n;i++){
cin>>a[i][0]>>a[i][1]>>a[i][2];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=w;j++){
if(j<a[i][0]){
dp[i][j]=dp[i-1][j];
}
else
dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i][0]]+a[i][1]);
}
}
int k=w;
for(int i=n;i>=1;i--){
if(dp[i][k]!=dp[i-1][k]){
cout<<i<<" ";
k=k-a[i][0];
}
}
return 0;
}
这个程序是用来解决“01背包问题”的,具体来说,它实现了一个动态规划算法来找出在给定的背包容量和物品的情况下,能够获得的最大价值,并且还输出了最优解中选择的物品编号。下面是对程序的逐行解读:
1. 头文件和全局变量声明
#include<bits/stdc++.h>
using namespace std;
int a[1001][3], dp[1001][10001];
#include<bits/stdc++.h>
:包含了所有标准库头文件,简化代码书写。a[1001][3]
:用于存储每个物品的属性。a[i][0]
表示物品的重量,a[i][1]
表示物品的价值,a[i][2]
(未用到)可能是用于其他信息。dp[1001][10001]
:用于存储动态规划的状态,dp[i][j]
表示在前i
个物品中,背包容量为j
时能获得的最大价值。
2. 主函数
int main() {
int w, n;
cin >> w >> n;
w
:背包的最大容量。n
:物品的数量。
for (int i = 0; i < n; i++) {
cin >> a[i][0] >> a[i][1];
}
- 输入每个物品的重量和价值。
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= w; j++) {
if (j < a[i-1][0]) {
dp[i][j] = dp[i-1][j];
} else {
dp[i][j] = max(dp[i-1][j], dp[i-1][j-a[i-1][0]] + a[i-1][1]);
}
}
}
- 使用动态规划来填充
dp
表。dp[i][j]
的值是通过考虑是否包含第i
个物品来更新的。- 如果当前背包容量
j
小于物品i
的重量,则不能放入这个物品,只能继承前一个状态dp[i-1][j]
。 - 否则,选择最大值:不放入这个物品的价值
dp[i-1][j]
和放入这个物品的价值dp[i-1][j-a[i-1][0]] + a[i-1][1]
。
- 如果当前背包容量
int k = w;
for (int i = n; i >= 1; i--) {
if (dp[i][k] != dp[i-1][k]) {
cout << i << " ";
k = k - a[i-1][0];
}
}
return 0;
}
- 从
dp
表中反向追踪选择的物品。根据dp
表中状态的变化来确定哪些物品被选中。如果dp[i][k]
与dp[i-1][k]
不同,则说明第i
个物品被选中。- 打印出被选中的物品编号,并更新背包容量
k
,减少相应物品的重量。
- 打印出被选中的物品编号,并更新背包容量
总结
这个程序通过动态规划解决了01背包问题,并输出了在给定背包容量下能够获得的最大价值和选择的物品编号。程序利用二维 dp
数组来存储子问题的解,并最终从 dp
数组中反向追踪出最终的解。