ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

背包问题

2021-09-06 11:01:48  阅读:129  来源: 互联网

标签:vector 背包 int 问题 件物品 物品 dp


问题描述


       背包问题是一种组合优化的 NP 完全问题:有 N 个物品和容量为 W 的背包,每个物品都有自己的体积 w 和价值 v,求拿哪些物品可以使得背包所装下物品的总价值最大。如果限定每种物品只能选择 0 个或 1 个,则问题称为 0-1 背包问题;如果不限定每种物品的数量,则问题称为无界背包问题或完全背包问题。

输入输出样例

       输入物品的数量,背包最大容量,每件物品的重量和价值,输出背包所能装下的物品最大价值。

Input: 5

           8

           [3, 5, 2, 1, 4]

           [4, 5, 3, 2, 2]

Output: 10

      输出结果为10:当背包装物品2,3,4时价值最大为10。


动态规划:

      我们可以用动态规划来解决背包问题。动态规划解法的关键是找到正确的状态转移方程:以 0-1 背包问题为例,我们可以定义一个二维数组 dp存储最大价值,其中 dp[i][j] 表示前 件物品体积不超过 的情况下能达到的最大价值。在我们遍历到第 i 件物品时,在当前背包总容量为 j 的情况下,如果我们不将物品 i 放入背包,那么动态规划方程为:dp[i][j]= dp[i-1][j],即前 i 个物品的最大价值等于只取前 i-1 个物品时的最大价值;如果我们将物品 i 放入背包,假设第 i 件物品体积为 w,价值为 v,那么我们得到动态规划方程: dp[i][j] = dp[i-1][j-w] + v。我们只需在遍历过程中对这两种情况取最大值即可。

代码:

#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;

int knapsack(vector<int> weights, vector<int> values, int N, int W) {
    vector<vector<int>> dp(N + 1, vector<int>(W + 1, 0));
    for (int i = 1; i <= N; ++i) {
        int w = weights[i - 1], v = values[i - 1];
        for (int j = 1; i <= W; ++j) {
            if (j >= w) {
                //状态转移方程:dp[i][j]为不放入第i件物品和放入i件物品两种情况的价值的最大值
                //如果放入第i件物品,前i-1件物品总重不超过j-w
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w] + v);
                /*
                完全背包问题的转移状态方程
                dp[i][j] = max(dp[i - 1][j], dp[i][j - w] + v);
                */
            }
            else {
                //边界条件:在容量为j时,如果物品i的重量w大于j,则不能放入i
                dp[i - 1][j] = dp[i - 1][j];
            }
        }
    }
    return dp[N][W];
}

int main() {
    int N = 5, W = 8;
    vector<int> weights = { 3,5,2,1,4 }, values = { 4,5,3,2,2 };
    int result = knapsack(weights, values, N, W);
    cout << result;
}

 

 

 




标签:vector,背包,int,问题,件物品,物品,dp
来源: https://www.cnblogs.com/chang-yuan/p/15232364.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有