`

动态规划之0/1背包问题

 
阅读更多

背包问题

它是在1978年由Merkel和Hellman提出的。它的主要思路是假定某人拥有大量物品,重量各不同。此人通过秘密地选择一部分物品并将它们放 到背包中来加密消息。背包中的物品中重量是公开的,所有可能的物品也是公开的,但背包中的物品是保密的。附加一定的限制条件,给出重量,而要列出可能的物 品,在计算上是不可实现的。背包问题是熟知的不可计算问题,背包体制以其加密,解密速度快而其人注目。但是,大多数一次背包体制均被破译了,因此现在很少有人使用它。
0/1背包问题
  有N件物品和一个容量为V的背包。第i件物品的费用是c,价值是w。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
  基本思路
  这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
  用子问题定义状态:即f[v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[v]=max{f[v],f[v-c]+w}。
  这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细 解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。 如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”;如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为 v-c的背包中”,此时能获得的最大价值就是f [v-c]再加上通过放入第i件物品获得的价值w。
  注意f[v]有意义当且仅当存在一个前i件物品的子集,其费用总和为v。所以按照这个方程递推 完毕后,最终的答案并不一定是f[N] [V],而是f[N][0..V]的最大值。如果将状态的定义中的“恰”字去掉,在转移方程中就要再加入一项f[v-1],这样就可以保证f[N] [V]就是最后的答案。至于为什么这样就可以,由你自己来体会了。
  优化空间复杂度
  以上方法的时间和空间复杂度均为O(N*V),其中时间复杂度基本已经不能再优化了,但空间复杂度却可以优化到O(V)。

下面看一道最基础的o/1背包问题:

poj 3624:

题意:给你n件物品以及这n件物品的质量与价值,另外给你一个背包以及背包自身的最大容量,求在满足背包最大容量的条件下的,所装物品的最大价值。

思路参见0/1背包问题。

代码参考如下:

#include<iostream>
using namespace std;
const int mMax = 3500;
const int nMax = 14000;

struct
{
	int wei, val;
}obj[mMax];

int main()
{
    int n, m, i, w, dp[nMax];
    cin >> n >> m;
    for(i = 1; i <= n; i ++)
        cin >> obj[i].wei >> obj[i].val;     //  改为scanf()会省跑100多MS。
    memset(dp, 0, sizeof(dp));
	
    for(i = 1; i <= n; i ++)
        for(w = m; w >= obj[i].wei; w --)    //  必须从后往前dp,因为前面的数会影响后面的。
            if(dp[w] < dp[w - obj[i].wei] + obj[i].val)
                dp[w] = dp[w - obj[i].wei] + obj[i].val;
			cout << dp[m] << endl;
			return 0;
}

 关于0/1背包问题,接下来自己还会深入学习。

分享到:
评论

相关推荐

    0/1背包问题(蛮力、动态规划、回溯、分支限界法)

    ### 0/1背包问题(蛮力、动态规划、回溯、分支限界法) #### 实验背景 0/1背包问题是计算机科学中一个经典的组合优化问题,涉及到资源分配、决策选择等多个方面,在实际生活中也有着广泛的应用场景,如物流管理、...

    动态规划—0/1背包问题

    总的来说,0/1背包问题的动态规划解决方案是通过递归地构建子问题的最优解,避免了重复计算,从而有效地找到了全局最优解。这是一种强大而灵活的工具,不仅适用于0/1背包问题,还可以应用于许多其他类型的优化问题。

    动态规划法解0-1背包问题

    算法实验中用动态规划法解0-1背包问题,这里提供了源代码,仅供参考

    0/1背包问题 动态规划 Java代码实现

    动态规划不仅在0/1背包问题中应用广泛,还可以应用于其他问题,如最长公共子序列、最短路径问题等。其核心思想是避免重复计算,通过存储中间结果来提高效率。在Java编程中,熟练掌握动态规划可以有效解决复杂度较高...

    用动态规划法求解0/1背包问题

    在本例中,我们将通过C++语言和VC++6.0环境来探讨如何运用动态规划策略求解0/1背包问题。 0/1背包问题的基本描述是这样的:我们有一组物品,每件物品都有一个重量和一个价值,我们需要决定哪些物品放入一个容量有限...

    0/1背包问题的动态规划

    ### 0/1背包问题的动态规划 #### 实验目的及要求 本次实验的主要目的是让学生通过实际编程操作来深入理解并掌握动态规划方法在解决背包问题中的应用。具体要求包括: 1. **理论掌握**:了解动态规划的基本原理...

    0/1背包问题相关算法

    动态规划是解决0/1背包问题的常用方法,因为它保证找到最优解且效率相对较高。然而,对于特殊结构或约束的背包问题,其他算法可能会更有效。实际应用中,常常需要根据问题的具体特点和规模选择合适的求解策略。

    动态规划求解0-1背包问题的改进算法完整解释

    动态规划求解0-1背包问题的改进算法完整解释 在计算机算法设计与分析中,动态规划法是解决背包问题的常用方法之一。所谓背包问题,是指在有限的背包容量下,如何选择物品来达到最大价值的问题。在本文中,我们将对...

    动态规划解决0-1背包问题

    动态规划是一种有效的算法设计策略,尤其适用于解决具有重叠子问题和最优子结构的问题,而0-1背包问题就是这种策略的一个典型应用。0-1背包问题是一个经典的组合优化问题,它源自实际生活中的资源分配问题,比如在...

    C# 0/1背包问题过程演示源码

    总结来说,0/1背包问题是计算机科学中的一个经典问题,动态规划是解决这类问题的有效工具。通过分析和理解C#源码,你可以深入理解动态规划的工作原理,并能将其应用到其他类似的问题中。这不仅有助于提升编程技能,...

    采用优先队列式分枝限界法求解0/1背包问 题.pdf

    优先队列式分枝限界法在解决0/1背包问题时,相比于其他算法如动态规划,特别适用于求解大规模问题,因为它的搜索过程是按需的,即只探索可能达到最优解的部分。这种方法不需要预先生成所有可能的解空间,因此能够...

    0/1背包问题源代码

    动态规划是解决0/1背包问题的常见方法。我们可以创建一个二维数组`dp`,其中`dp[i][w]`表示在前`i`件物品中选取总重量不超过`w`时能获得的最大价值。状态转移方程为: ```markdown dp[i][w] = max(dp[i-1][w], dp[i...

    0/1背包问题

    在C#实现的0/1背包问题中,通常会采用动态规划的方法来解决。动态规划是一种将大问题分解为小问题并逐个解决的策略,它通过构建一个二维数组(通常是dp数组)来存储子问题的解,从而避免了重复计算。对于0/1背包问题...

    动态规划解决0-1背包问题(c++)

    背包的重量有限,每次只可取一种商品。利用动态规划实现所选商品总价值的最大值。

    动态规划法和回溯法求0-1背包问题

    ### 动态规划法与回溯法解决0-1背包问题 #### 一、实验目的与背景 0-1背包问题是一种经典的组合优化问题,在实际应用中有着广泛的用途,例如资源分配、投资组合等问题都可以抽象成背包问题的形式。本实验旨在通过...

    动态规划法求解0-1背包问题实验报告.pdf

    0-1背包问题是一个经典的优化问题,主要涉及动态规划算法的运用。在这个实验报告中,学生使用Java语言解决了一个0-1背包问题的实例。以下是关于这个问题和解决方案的详细解释。 一、问题描述: 0-1背包问题的核心是...

    动态规划法解决0-1背包问题

    基于MATLAB平台,用动态规划法解决0-1背包问题,较为简单。参数分别为[物品重量,物品价值,背包容量,背包价值]

Global site tag (gtag.js) - Google Analytics