例题12.7 点菜问题(北京大学复试)链接
关键字:0-1背包、动态规划
算法:设计dp[i][j] 用来存储将物品i放入背包中后可以达到的最大的价值j
分两种情况:
CASE1: 当前背包没有足够空间,无法将商品 i 放入其中,此时的转移方程即为dp[i][j] = dp[i-1][j]
CASE2: 当前背包的空间充足,可以放入当前的商品i,这时候需要考虑两种情况,即将商品i放入其中取得的最大价值和不将商品i放入取得的最大价值中最大的那一个,此时转移方程为dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i]] + value[i])
#include<iostream>
#include<vector>
using namespace std;
int main() {
int m, n;
while (cin >> m && cin >> n) {
vector<int> price(n+1,0);
vector<int> value(n+1,0);
//1.输入数据
for (int i = 1; i <= n; i++) {
cin >> price[i];
cin >> value[i];
}
//2.根据转移方程计算最大价值
vector<vector<int>> dp(n + 1, vector<int>(m + 1,0));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
//2.1如果该商品价格过高,剩余的钱无法支付,则i商品不放入背包中
if (j - price[i] < 0) {
dp[i][j] = dp[i - 1][j];
}
//2.2如果该商品可以放入背包,则选择在这两种情况中判断即 max(不放入背包的最大价值,放入背包的最大价值)
else {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - price[i] ]+ value[i]);
}
}
}
cout << dp[n][m] << endl;
}
return 0;
}