//0 - 1 背包问题:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。
//
//问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?
#include <iostream>
#include <vector>
using namespace std;
/*
* val[n][vol]为最优解, 如果val[n-1][vol] = val[n][vol]说明第n件物品没有被拿, 如果第n件物品被拿, vol = vol - weight[n-1], 然后继续判断
*/
vector<int> trackback(int vol, int n, const vector<vector<int>>& val, int weight[]) {
vector<int> use(n);
for (int i = 1; i <= n; ++i) {
if (val[i][vol] == val[i - 1][vol]) {
use[i - 1] = 0;
}
else {
use[i - 1] = 1;
vol = vol - weight[i - 1];
}
}
return use;
}
int main() {
int n, vol;
cin >> n >> vol;
int *weight = new int[n]();
int *tr = new int[n]();
for (int i = 0; i < n; ++i)
{
cin >> weight[i];
}
for (int i = 0; i < n; ++i)
{
cin >> tr[i];
}
vector<vector<int>> val(n + 1, vector<int>(vol + 1, 0));
/*vector<vector<int>> val(n);
for (int i = 0; i <= n; ++i)
{
val[i].resize(vol);
}*/
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= vol; ++j)
{
if (j >= weight[i - 1] && (val[i - 1][j - weight[i - 1]] + tr[i - 1] > val[i - 1][j]))
{
val[i][j] = val[i - 1][j - weight[i - 1]] + tr[i - 1];
}
else {
val[i][j] = val[i - 1][j];
}
}
}
cout << val[n][vol] << endl;
vector<int> res = trackback(vol, n, val, weight);
for (auto it = res.begin(); it != res.end(); ++it)
cout << *it << endl;
}
01背包空间优化
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
//N代表物品数量, vol代表背包容量
int N, vol;
cin >> N >> vol;
int *weight = new int[N +1](); // weight[] 数组代表物品对应的价值
int *spa = new int[N + 1](); // spa[]数组代表物品消耗的空间
int *dp = new int[vol + 1](); // dp[]数组代表i个物品在不同容量下的所装的最大价值
for (int i = 0; i < N; ++i) {
cin >> spa[i];
}
for (int i = 0; i < N; ++i) {
cin >> weight[i];
}
//物品标号从1开始
for (int i = 1; i <= N; ++i) {
for (int j = vol; j >= weight[i - 1]; --j) {
dp[j] = max(dp[j], dp[j - spa[i - 1]] + weight[i - 1]);
}
}
cout << "背包所能装下的最大的价值: " << dp[vol] << endl;
delete[] weight;
delete[] spa;
delete[] dp;
}