本文主要是介绍01背包【B站正月点灯笼讲解版和yxc版】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
yxc版
题目链接
从1开始,f[i][j]表示前i个物品占用j空间的最大价值。
v表示第i件物品的体积,p表示第i件物品的价值。
f[i][j]可以有两个转移来源。
- 不选第i个物品:
f[i][j] = f[i-1][j]
- 选第i个物品:
f[i][j] = f[i-1][j - v[i]] + p[i]
时间复杂度 O ( n m ) O(nm) O(nm)
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int f[N][N];
int v[N], w[N];
int n, m;
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 = 1; j <= m; j++){f[i][j] = f[i-1][j];if(j >= v[i]){f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]);}}}int res = 0;for(int i = 1; i <= m; i++) res = max(res, f[n][i]);cout<<res<<endl;return 0;
}
核心代码
使用滚动数组将二维的数据优化为一维,降低了空间复杂度。
直接套模板
//物品数量是5 最大容量是 20
int d[21]={0};
void knapsack2(){for(int i = 1; i <= 5; i++){for(int c = 20; c >= w[i]; c--){d[c] = max(d[c], d[c - w[i]] + v[i]);}}
}
完整版
根据B站灯神视频讲解改写而成
#include<iostream>
using namespace std;
int dp[6][21] = {0}; //dp[i][c]表示前i件物品恰好装入容量为c的背包所能获得的最大价值
int d[21]={0};
int w[] = {0, 2, 3, 4, 5, 9};//读入的时候做个偏移
int v[] = {0, 3, 4, 5, 8, 10};
//物品数量是5 最大容量是 20
void knapsack(){for(int i = 1; i <= 5; i++){for(int c = 1; c <= 20; c++){ //从1开始 if(c >= w[i]) dp[i][c] = max(dp[i-1][c], dp[i-1][c - w[i]] + v[i]);//放与不放 else //第i件物品太重了 dp[i][c] = dp[i - 1][c];}}
}
//物品数量是5 最大容量是 20
void knapsack2(){for(int i = 1; i <= 5; i++){for(int c = 20; c >= w[i]; c--){d[c] = max(d[c], d[c - w[i]] + v[i]);}}
}int main(){knapsack2();for(int i = 0; i <= 20; i++) cout<<d[i]<<" "; return 0;
}
这篇关于01背包【B站正月点灯笼讲解版和yxc版】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!