0-1背包问题
Posted 超霸霸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0-1背包问题相关的知识,希望对你有一定的参考价值。
0-1背包问题
-
问题:
给定一个背包和若个物品,书包的体积为W,物品的数量为N,且每个物品都有对应的体积wi和价值vi,求当怎样装物品使得书包中物品的价值总和最大?
-
解题思路:
- 宏观:这是一个典型的动态规划问题,我们采用填表的方式来解题。设置一个二维数组
dp
,dp[i][w]
表示对应前i个物品,背包体积为w,该情况下书包能装物品的最大价值,则dp[N][W]
即为我们要求的结果,我们要做的就是遍历这张表,将数据一个一个计算填入最后求出dp[N][W]
- 微观:在计算
dp[i][w]
时,我们先判断第i个物品是否能放得下,若不能则dp[i][w]=dp[i-1][w]
;若放得下,我们则求将第i个物品放进和不放进两种情况中背包价值更大的值:若不放进,则dp[i][w]=dp[i-1][w]
,若放进,则dp[i][w]=dp[i-1][w-w[i]]+v[i]
,返回两者中较大的即可
- 宏观:这是一个典型的动态规划问题,我们采用填表的方式来解题。设置一个二维数组
-
例子:
假设N=3,W=4,w=[2,1,3],v=[4,2,3],则dp表如下i/w 0 1 2 3 4 0 0 0 0 0 0 1 0 0 4 4 4 2 0 2 4 6 6 3 0 2 4 6 6 -
代码
#include<iostream> #include<algorithm> #include<vector> using namespace std; int knapsack(int W, int N, vector<int>& wt, vector<int>& vt) { //dp为二维数组,并初始化为0 vector<vector<int>> dp(N + 1, vector<int>(W + 1, 0)); for (int i = 1; i <= N; i++) { for (int w = 1; w <= W; w++) { //第i个物品放不下 if (w - wt[i - 1] < 0) { dp[i][w] = dp[i - 1][w]; } //第i个物品放得下 else { dp[i][w] = max(dp[i - 1][w - wt[i - 1]] + vt[i - 1], dp[i - 1][w]); } } } return dp[N][W]; } int main() { //W为总容量,N为物品个数 int W, N; cin >> W >> N; //w为重量数组,v为价值数组 vector<int> w; vector<int> v; //输入每个物品的重量和价值 for (int i = 0; i < N; i++) { int wi, vi; cin >> wi; w.push_back(wi); cin >> vi; v.push_back(vi); } cout << knapsack(W, N, w, v); return 0; }
以上是关于0-1背包问题的主要内容,如果未能解决你的问题,请参考以下文章