dp解法:
令dp[i]表示容量为i的背包所能得到的最大价值,考虑在当前物品集合中加入1个新考虑的物品i,则有如下状态转移方程:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
#include <bits/stdc++.h>
using namespace std;
const int M = 1e4;
typedef pair<int, vector<int> > piv;
struct Node {
int weight, value;
int id;
void read() {
cin >> weight >> value;
}
void solve(piv dp[], int M) {
for (int i = M; i >= weight; i --) {
if (dp[i - weight].first + value > dp[i].first) {
dp[i].first = dp[i - weight].first + value;
dp[i].second = dp[i - weight].second;
dp[i].second.push_back(id);
}
}
}
};
int n, m;
piv dp[M];
int main() {
puts("请输入背包容量和物品个数:");
cin >> m >> n;
puts("请输入每个背包的重量(体积)和价值");
Node things;
for (int i = 0; i < n; i ++) {
things.read();
things.id = i + 1;
things.solve(dp, m);
}
cout << "最大价值为:" << dp[m].first << endl;
puts("选择的物品编号:");
for (int i = 0; i < dp[m].second.size(); i ++) {
cout << dp[m].second[i] << " ";
}
cout << endl;
return 0;
}
贪心解法:
按部分背包的贪心策略,优先考虑单位价值高的物品,于是只需要按单位价值从高到低排序,然后依次考虑,能放则放即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e2;
struct Node {
int weight, value;
int id;
void read() {
cin >> weight >> value;
}
// 单位价值高的放前面
bool operator< (const Node &that) const {
return value * that.weight > that.value * weight;
}
};
Node things[N];
int n, m;
int main() {
puts("请输入背包容量和物品个数:");
cin >> m >> n;
puts("请输入每个背包的重量(体积)和价值");
for (int i = 0; i < n; i ++) {
things[i].read();
things[i].id = i + 1;
}
sort(things, things + n);
int ans = 0;
vector<int> V;
for (int i = 0; i < n; i ++) {
if (m >= things[i].weight) {
ans += things[i].value;
m -= things[i].weight;
V.push_back(things[i].id);
}
}
cout << "最大价值为:" << ans << endl;
puts("选择的物品编号为:");
for (int i = 0; i < V.size(); i ++) {
cout << V[i] << " ";
}
cout << endl;
return 0;
}