有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 *vi*,价值是 *wi*。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi, *wi*,用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
0<*N**, V≤1000
0<*vi,*wi*≤1000
输入样例
输出样例
模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <iostream> #include <algorithm>
using namespace std;
const int N = 1010;
int n, m; int v[N], w[N]; int dp[N][N];
int main() { cin >> n >> m; for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i]; for (int i = 1; i <= n; i ++) for (int j = 0; j <= m; j ++) { dp[i][j] = dp[i - 1][j]; if (j >= v[i]) dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]); } cout << dp[n][m] << endl; return 0; }
|
状态压缩转化成一维
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <iostream> #include <algorithm>
using namespace std;
const int N = 1010;
int n, m; int v[N], w[N]; int dp[N];
int main() { cin >> n >> m; for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i]; for (int i = 1; i <= n; i ++) for (int j = m; j >= v[i]; j --) dp[j] = max(dp[j], dp[j - v[i]] + w[i]); cout << dp[m] << endl; return 0; }
|
换个写法,因为最外层只是遍历所有物品,所以可以每读入一个物品就遍历一遍,更加简洁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <iostream> #include <algorithm>
using namespace std;
const int N = 1010;
int n, m; int dp[N];
int main() { cin >> n >> m; for (int i = 0; i < n; i ++) { int v, w; cin >> v >> w; for (int j = m; j >= v; j --) dp[j] = max(dp[j], dp[j - v] + w); } cout << dp[m] << endl; return 0; }
|