acwing 2 零一背包问题

acwing 2 零一背包问题
强烈推介IDEA2021.1.3破解激活,IntelliJ IDEA 注册码,2021.1.3IDEA 激活码  

大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说acwing 2 零一背包问题,希望能够帮助大家进步!!!

地址 https://www.acwing.com/problem/content/description/2/

 

题目描述
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式
输出一个整数,表示最大价值。

数据范围
0<N,V≤1000
0<vi,wi≤1000

样例
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8

 

算法1
(初步动态规划)
最开始的动态规划想法 就是二维数组
dp[i][j]记录 在选择i个物品下 j背包容积下的最大价值
状态转移方程式

C++ 代码

acwing 2 零一背包问题
acwing 2 零一背包问题

 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int N= 1010;
 7 
 8 int n,m;
 9 
10 int dp[N][N];
11 int v[N];
12 int w[N];
13 
14 int main()
15 {
16 cin >> n >> m;
17 
18 for(int i = 1;i <= n;i++){
19 cin >> v[i] >> w[i];
20 }
21 
22 for(int i = 1;i<=n;i++){
23 for(int j = 1;j<=m;j++){
24 dp[i][j] = dp[i-1][j];
25 if(j >= v[i])
26 dp[i][j] = max(dp[i-1][j] , dp[i-1][j-v[i]]+w[i]);
27 }
28 }
29 
30 cout << dp[n][m];
31 
32 
33 return 0; 
34 }

View Code

 

根据acwing up主的视频和网络上的《背包九讲》 空间存储上还可在优化
算法2
(进阶动态规划)
我们可以将二维DP降为一维DP
这个可以看做在i的循环情况下 我们每次计算j(容量)的可装的最大价值
那么初次进入i+1 的循环时候,我们需要利用i轮次的结果来计算i+1的结果
dp[i+1][j]在0 1 情况下只有两种可能 在上一轮的结果下 选择放入当前物品 或者不放入当前物品
1 不放入当前物品的话
那么 dp[i+1][j] = dp[i][j]; //利用上一轮的结果
2 放入当前物品的话
那么 dp[i+1][j] = dp[i][j-v[i]]+w[i]; //利用上一轮的结果

由于我们始终只需要最新的i+1层的结果 那么实际上可以使用一维数组dp[j]来记录每层的结果,
当从i层进入i+1层后,dp[i+1][j]的结果 实际可以使用dp[i][j]存储,其实就是 dp[j] = dp[j];j++(或者j–);

由于计算机语言的特性,在执行dp[j] = dp[j]的时候 我们必须保证等号右边的dp[j]是没被改动过的,这就要保证j是降序
因为dp[j]= max(dp[j],dp[j-v[i]]); dp[j]的赋值对低于j的[j-v[i]]有依赖,必须降序排列,才能保证赋值的时候等号右边的dp[j]是没被改动过的

C++ 代码

acwing 2 零一背包问题
acwing 2 零一背包问题

 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int N= 1010;
 7 
 8 int n,m;
 9 
10 int dp[N];
11 int v[N];
12 int w[N];
13 
14 int main()
15 {
16 cin >> n >> m;
17 
18 for(int i = 1;i <= n;i++){
19 cin >> v[i] >> w[i];
20 }
21 
22 for(int i = 1;i<=n;i++){
23 for(int j = m;j>= v[i];j--){
24 dp[j] = max(dp[j] , dp[j-v[i]]+w[i]);
25 }
26 }
27 
28 cout << dp[m];
29 
30 return 0; 
31 }

View Code

 

作者:defddr
链接:https://www.acwing.com/solution/acwing/content/2170/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载于:https://www.cnblogs.com/itdef/p/10906302.html

本文来源weixin_30595035,由架构君转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/29804

发表评论