首页 > 其他分享 >0-1 背包问题

0-1 背包问题

时间:2024-11-24 15:33:19浏览次数:7  
标签:背包 capacity 问题 物品 价值 dp 贪心

目录

背包问题是一种经典的优化问题,常见的形式有 0-1 背包问题和完全背包问题。这里将介绍 0-1 背包问题的动态规划求解方法。

问题描述

给定一组物品,每个物品都有一定的重量 \(w_i\) 和价值 \(v_i\),目标是选择一些物品,使得它们的总重量不超过背包的最大承重 \(C\),同时使得总价值最大化。

动态规划解法

1. 定义状态

定义 dp[i][j] 表示前 i 个物品放入容量为 j 的背包的最大价值。

2. 状态转移方程

  • 如果不选择第 i 个物品:

    \[dp[i][j] = dp[i-1][j] \]

  • 如果选择第 i 个物品(前提是它的重量小于等于 j):

    \[dp[i][j] = dp[i-1][j - weight[i-1]] + value[i-1] \]

  • 综合考虑,状态转移方程为:

    \[dp[i][j] = \begin{cases} dp[i-1][j] & \text{if } weight[i-1] > j \\ \max(dp[i-1][j], dp[i-1][j - weight[i-1]] + value[i-1]) & \text{otherwise} \end{cases} \]

3. 初始化

  • dp[0][j] = 0,表示没有物品时,价值为 0。
  • dp[i][0] = 0,表示背包容量为 0 时,价值也为 0。

4. 实现细节

通常我们只需要当前行和上一行的值,因此可以优化空间复杂度,使用一维数组代替二维数组。

Python 示例代码

以下是 0-1 背包问题的动态规划实现:

def knapsack(weights, values, capacity):
    n = len(weights)
    dp = [0] * (capacity + 1)

    for i in range(n):
        for j in range(capacity, weights[i] - 1, -1):
            dp[j] = max(dp[j], dp[j - weights[i]] + values[i])

    return dp[capacity]

# 示例数据
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 5

max_value = knapsack(weights, values, capacity)
print("最大价值:", max_value)

复杂度分析

  • 时间复杂度:O(n * capacity),其中 n 是物品数量。
  • 空间复杂度:O(capacity),因为我们使用了一维数组来存储结果。

结论

动态规划是一种有效的求解背包问题的方法,通过构建状态转移方程和优化存储,可以高效地计算出最大价值。

0-1 背包问题通常不能用贪心算法来求解,因为贪心算法并不总是能够找到最优解。贪心法适合于某些特定的背包问题,例如完全背包问题或分数背包问题(fractional knapsack problem),但对于 0-1 背包问题,贪心法可能会得到次优解。

贪心法求解

在 0-1 背包问题中,每个物品只能选择一次。贪心法的思路是选择当前最优的物品,然而这并不保证整体的最优解。下面是一个简要的说明以及示例,展示贪心法为何不适用于 0-1 背包问题。

贪心法的想法

贪心法通常会根据某种准则(如价值密度)选择物品。对于 0-1 背包问题,可以考虑以下步骤:

  1. 计算价值密度:计算每个物品的价值密度(价值/重量)。
  2. 按价值密度排序:将物品按价值密度从高到低排序。
  3. 选择物品:依次选择物品,直到背包满。

示例

假设有以下物品和背包容量:

  • 物品1:重量 1,价值 1
  • 物品2:重量 3,价值 4
  • 物品3:重量 4,价值 5
  • 物品4:重量 5,价值 7

背包容量为 7。

贪心选择过程

  1. 计算价值密度:

    • 物品1:1/1 = 1
    • 物品2:4/3 ≈ 1.33
    • 物品3:5/4 = 1.25
    • 物品4:7/5 = 1.4
  2. 按价值密度排序:

    • 物品4(1.4)
    • 物品2(1.33)
    • 物品3(1.25)
    • 物品1(1)
  3. 选择物品:

    • 选择物品4(重量 5,价值 7),剩余容量 2。
    • 选择物品2(重量 3,价值 4)不行,跳过。
    • 选择物品3(重量 4,价值 5)不行,跳过。
    • 选择物品1(重量 1,价值 1),剩余容量 1。

最终得到的总价值为 8(物品4 + 物品1),但最优解是物品2和物品3,总价值为 9。

结论

由于贪心算法只关注当前的局部最优选择,无法保证获得全局最优解,因此不适用于 0-1 背包问题。对于 0-1 背包问题,推荐使用动态规划方法,以确保能够找到最优解。

标签:背包,capacity,问题,物品,价值,dp,贪心
From: https://www.cnblogs.com/Mount256/p/18565868

相关文章

  • Accessibility.dll文件丢失导致程序无法运行问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个Accessibility.dll文件(挑选合适的版本文件)......
  • STM32 系统滴答定时器和时间换算问题
    ARMCPU内部存在定时器SysTick可以称为系统滴答定时器,需要查看Cortex-M3->STK_CRTL控制和状态寄存器:32位寄存器:reserved保留0位:ENABLE:使能位,写1开始计时16位:COUNTFALG:标志位,计数完成自动置1。1位:TICKINT:中断使能,定时完成是否发生中断,0是默认关闭2位:CLKSOURCE:时钟源......
  • matplotlib的GUI方式和非GUI方式带来的内存泄漏问题
    更新:居然靠这篇文章解决了。。。matplotlib的后端修改后,直接就不出现内存持续增长的情况了。。。我还以为各个样的其他的内存泄漏和引用的问题,还添加ImageManager,还在试图用单例模式,防止内存泄漏。。。不知道应该是撒花还是。。。。记录使用matplotlib绘图遇到的内存泄......
  • 读数据质量管理:数据可靠性与数据质量问题解决之道13数据沿袭
    1. 数据沿袭1.1. MyDoom的病毒1.2. 现在,许多团队甚至整个公司都在使用数据,这要求数据管理的方式要更便于合作,同时也更不容许发生错误1.3. 从采用dbt和ApacheAirflow等开源工具来实现数据转换和编排,到使用Snowflake和Databricks等云端数据仓库和数据湖1.4. 数据仪表板和......
  • 高通android手机蓝牙重启问题分析
    问题背景这两天芯片厂更新了芯片的固件,然而我们用高通平台手机去配对(其他平台手机没这个问题),发现手机蓝牙会重启,下面就开始debug之路:问题分析先看手机logcatlog手机蓝牙重启自然先看一下手机端的logcatlog,一般这种手机蓝牙重启就说明蓝牙进程发生了crash之类的,导致蓝......
  • 动态规划-二维费用问题——879.盈利计划
    1.题目解析 题目来源879.盈利计划——力扣 测试用例2.算法原理 1.状态表示2.状态转移方程3.初始化4.填表顺序i下标从小到大即可,j与k下标不用特殊要求5.返回值 返回最后一个位置的dp值,即dp[group.size()][n][minProfit]3.实战代码classSoluti......
  • 动态规划-二维费用问题——474.一和零
    1.题目解析 题目来源474.一和零——力扣 测试用例2.算法原理1.状态表示本题是一个二维费用的问题,如果一开始直接使用二维dp表来表示比较困难,所以不妨直接使用三维dp表先来理解:dp[i][j][k]:在区间[1,i]上选择字符串,此时在字符0的总和不大于j且字符1的总和不......
  • 设计模式问题汇总
    因为很多时候完成技术选型后,走逻辑的时候总发现软件设计中普遍存在(反复出现)的各种因为设计而产生的冗余性问题,就所提出的解决方案而言,总是没有一个很好的汇总,因此今天搬运一些常见的设计模式(虽然有好几种都没用过hhhhh)。设计模式典型应用框架中的应用工厂方法适合在单个产......
  • 【K8S问题系列 | 15】资源配额不足导致Pod无法调度的场景如何处理
    在Kubernetes中,资源配额不足可能导致Pod无法调度,这种情况通常发生在命名空间的资源使用达到了设定的上限。以下是一些处理这类情况的策略和方法:1.监控资源使用情况实施监控使用监控工具(如Prometheus和Grafana)实时监控命名空间和集群的资源使用情况。设置告警规......
  • Kafka创建不了topic问题,定位1个月的现场血案,居然如此简单
    背景        2022年某天,我还在happy的看着电影。突然,手上握着的红米手机响起了周杰伦《回到过去》的铃声。哟,现场童鞋又来电话了,一接听电话,就响起了比较焦急的声音,“哥,现场有个Kafka集群创建不了topic了,赶紧帮忙看下!”,不爽,今天是周六,本来休息的时间,但是谁叫咱们有现场......