题目描述
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤1000
0<vi,wi≤1000
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8
时间复杂度: O(n * c)
C ++代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1010;
int main(){
int n, c;//n表示物体数量, c表示背包容积
int p[N][N];//备忘录p[i][j]表示在前i个商品中选择,背包容量为j时的最大价格(最优解).
int w[N], v[N];// vi, wi 分别表示第 i 件物品的体积和价值
cin >> n >> c;
for(int i = 1; i <= n; i ++) cin >> v[i] >> w[i];
//初始化
int rec[N][N];//记录方案
memset(rec, 0, sizeof rec);
for(int i = 0; i <= n; i ++) p[i][0] = 0; //背包体积为0时,总价格均为0
for(int j = 0; j <= c; j ++) p[0][j] = 0;//没有物品可选时,总价格均为0
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= c; j ++){
if(v[i] <= j && (p[i - 1][j - v[i]] + w[i] > p[i - 1][j])){
p[i][j] = p[i - 1][j - v[i]] + w[i];//选第i个物品
rec[i][j] = 1;//rec == 1, 表示选择第i个物品
}
else{
p[i][j] = p[i - 1][j];//不选第i个物品
rec[i][j] = 0;//rec == 0, 表示不选择第i个物品
}
}
}
cout << p[n][c] << endl;//输出最优方案
//打印方案
int k = c;//
for(int i = n; i >= 1; i --){
if(rec[i][k] == 1){
printf("选择商品%d\n", i);
k = k - v[i];//向前追踪方案
}
else{
printf("不选择商品%d\n", i);
}
}
return 0;
}
样例结果果展示:
8
不选择商品4
选择商品3
选择商品2
不选择商品1