有 N 件物品和一个容量是 V 的背包,每种物品都有无限件可用。
第 i 件物品的体积是 **vi **,价值是 **wi **。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。
输入格式 第一行两个整数,N ,V ,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi , **wi **,用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式 输出一个整数,表示最大价值。
数据范围 0<N**, V ≤1000 0<**vi , wi ≤1000
输入样例
输出样例
朴素动态规划O(n3 ) 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 #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 ++) for (int k = 0 ; k * v[i] <= j; k ++) dp[i][j] = max(dp[i][j], dp[i - 1 ][j - k * v[i]] + k * w[i]); cout << dp[n][m] << endl ; return 0 ; }
优化 O(n2 )
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][j - v[i]] + w[i]); } cout << dp[n][m] << endl ; return 0 ; }
状态压缩 只和01背包问题有遍历顺序的区别
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 = v[i]; j <= m; j ++) dp[j] = max(dp[j], dp[j - v[i]] + w[i]); cout << dp[m] << endl ; return 0 ; }