01背包问题的动态规划算法

01背包问题我最初学会的解法是回溯法,第一反应并不是用动态规划算法去解答。原因是学习动态规划算法的时候,矩阵连乘、最长公共子串等问题很容易将问题离散化成规模不同的子问题,比较好理解,而对于01背包问题则不容易想到将背包容量离散化抽象出子问题,从情感上先入为主也误以为动态规划算法不是解决01背包问题的好方法,实际上并不是这样的。另外,动态规划算法不对子问题进行重复计算,但是要自底向上将所有子问题都计算一遍,直到计算出最终问题的结果也就是我们要的答案,有点像爬山的感觉。

问题描述:给定n种物品和一背包,物品i的重量是wi,其价值为vi,背包的容量为C,求能装入背包的物品的最大价值。
用m(i,j)表示为从i到n的物品装入容量为j的背包能产生的最大价值,则能装入背包的物品最大价值为m(1,C)。
递归式为:

上面讲到,该问题是对背包的容量进行离散化,因此时间复杂度是O(nC)。

代码如下(用的变量名可能和上面有小出入,但是是自描述的):

#include<iostream>
using namespace std;

struct CARGO{
    int weight;
    int value;
};

const int totalWeight=10;
const int totalNumber=5;
CARGO goods[totalNumber]={{2,6},{2,3},{6,5},{5,4},{4,6}};

//1.使用时下标都从1开始;2.遇到复杂结构的初始化用memset方法。
int result[totalNumber+1][totalWeight+1]={0};

int myMax(int i,int j)
{
    return i>=j?i:j;
}

void dp()
{
    int i,j;

    //动态规划表达式的初始化
    i=totalNumber;
    for(j=1;j<=totalWeight;j++)
    {
        if(goods[i-1].weight>j)//为保证逻辑完整性,这个if没删掉
        {
            result[i][j]=0;
        }
        else
        {
            result[i][j]=goods[i-1].value;
        }
    }

    for(i=totalNumber-1;i>0;i--)
    {
        for(j=1;j<=totalWeight;j++)
        {
            if(goods[i-1].weight>j)
            {
                result[i][j]=result[i+1][j];
            }
            else
            {
                result[i][j]=myMax(result[i+1][j],result[i+1][j-goods[i-1].weight]+goods[i-1].value);
            }
        }
    }
}

int main()
{
    dp();
    cout<<result[1][totalWeight]<<endl;

    //是否理解:完成用result[totalNumber][totalWeight]表示背包最大value的代码(从前往后解决子问题的方法)。

    return 0;
}
时间: 2024-08-01 10:32:49

01背包问题的动态规划算法的相关文章

0-1背包问题(动态规划)

<span style="font-size:18px;">#include<iostream> #include<vector> #include<iterator> #include<algorithm> #include<string> using namespace std; /* *0-1背包问题(动态规划) */ vector<vector<int>> values;//valu

0-1背包的动态规划算法,部分背包的贪心算法和DP算法------算法导论

一.问题描述 0-1背包问题,部分背包问题.分别实现0-1背包的DP算法,部分背包的贪心算法和DP算法. 二.算法原理 (1)0-1背包的DP算法 0-1背包问题:有n件物品和一个容量为W的背包.第i件物品的重量是w[i],价值是v[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大.其中每种物品只有一件,可以选择放或者不放. 最优子结构性质:对于0-1问题,考虑重量至多W的最值钱的一包东西.如果去掉其中一个物品j,余下的必是除j以外的n-1件物品中,可以带走的重量

01背包问题【动态规划】

问题: 假设有n个物品,每个物品都是有重量的,同时每个物品也是有价值的,要求把这些物品放到一个背包中,这个背包的载重量是有限制的,怎么使得背包里面的物品总价值最大? 符号表示: N:物品个数 W:背包载重量 w[i]:物品i的重量(1<i<=N) v[i]:物品i的价值(1<i<=N) c[i, j]:到物品i为止,背包重量限制为j的最优解(1<i<=N, 1<j<=W) 分析: 最优解结构:对于物品i,只有两种情况,放入或不放入.假设物品i放入了是最优解的

算法学习 - 01背包问题(动态规划C++)

动态规划 01背包 问题描述 求解思路 代码实现 放入哪些物品 代码 动态规划 我在上一篇博客里已经讲了一点动态规划了,传送门:算法学习 - 动态规划(DP问题)(C++) 这里说一下,遇到动态规划应该如何去想,才能找到解决办法. 最主要的其实是要找状态转移的方程,例如上一篇博客里面,找的就是当前两条生产线的第i个station的最短时间和上一时刻的时间关系. minTime(station[1][i]) = minTime(station[1][i-1] + time[i], station[

1008-----算法笔记----------0-1背包问题(动态规划求解)

1.问题描述 给定n种物品和一个背包,物品i的重量是wi,其价值为vi,背包的容量为C.问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大? 2.问题分析 上述问题可以抽象为一个整数规划问题,即求满足 (a)Σwixi ≤ C:(b)xi ∈(0,1),  1≤i≤n:条件下,∑vixi最大时的一个物品xi序列.分析问题可以发现,该问题具有最优子结构性质,那么就可以尝试用动态规划方法求解,而动态规划求解的关键就是列出问题的递归关系表达式. 设m(i,j)为背包容量为j,可选物品为i,

0-1背包问题的动态规划实现

一,问题描述 给定一个背包,已知背包的最大承重为packageWeight,再给出若干件(numbers件)物品,已经每件物品的重量和对应的价值. 物品的重量存储在weight[]数组中,物品的价值存储在value[]数组中. 现在要求:应该挑选哪几件物品,使得背包装下最大的价值(注意:装的物品的重量不能超过背包的承重) (本文在最后打印出了装入了哪几件物品) 二,问题分析 这是一个典型的动态规划求解.对于每件物品而言,只有两种选择,要么选中它装入背包:要么不选它.因此,这是一个0-1背包问题,

从01背包问题理解动态规划---初体验

01背包问题具体例子:假设现有容量10kg的背包,另外有3个物品,分别为a1,a2,a3.物品a1重量为3kg,价值为4:物品a2重量为4kg,价值为5:物品a3重量为5kg,价值为6.将哪些物品放入背包可使得背包中的总价值最大? 这个问题有两种解法,动态规划和贪婪算法.本文仅涉及动态规划. 先不套用动态规划的具体定义,试着想,碰见这种题目,怎么解决? 首先想到的,一般是穷举法,一个一个地试,对于数目小的例子适用,如果容量增大,物品增多,这种方法就无用武之地了. 其次,可以先把价值最大的物体放入

01背包问题(动态规划)python实现

在01背包问题中,在选择是否要把一个物品加到背包中.必须把该物品加进去的子问题的解与不取该物品的子问题的解进行比較,这样的方式形成的问题导致了很多重叠子问题,使用动态规划来解决.n=5是物品的数量,c=10是书包能承受的重量,w=[2,2,6,5,4]是每一个物品的重量,v=[6,3,5,4,6]是每一个物品的价值,先把递归的定义写出来: 然后自底向上实现,代码例如以下: def bag(n,c,w,v): res=[[-1 for j in range(c+1)] for i in range

0-1背包问题_动态规划

普通背包问题可以用贪心来解决,而0-1背包问题只能靠动态规划来做,而且在我们平时的做题中经常会遇到0-1背包问题的变形,所以有必要牢牢掌握0-1背包问题的思想和解题思路. 根据下面的图更可以找到应该选那些背包 下面是我根据此思路模拟的代码 1 #include<bits/stdc++.h> 2 using namespace std; 3 int array3[100];//价值 4 int array1[100];//物品重量 5 int capacity;//容量 6 int n;//物品