动态规划算法深度解析:0-1背包问题(含完整流程)

news2025/4/17 22:05:39

简介:

0-1背包问题是经典的组合优化问题:给定一组物品(每个物品有重量和价值),在背包容量限制下选择物品装入背包,要求总价值最大化每个物品不可重复选取

动态规划核心思想

通过构建二维状态表dp[i][j],记录前i个物品在容量j时的最大价值,通过状态转移方程逐步推导最优解,避免重复计算子问题。


问题建模与参数定义
static final Integer N = 4;       // 物品数量
static final Integer W = 5;       // 背包容量
Integer[] w = {0,1,2,3,4};        // 物品重量数组(索引0占位)
Integer[] v = {0,2,4,5,6};        // 物品价值数组
private Integer[][] table = new Integer[N+1][W+1]; // DP状态表

代码执行全流程解析

1. 初始化阶段 init()
for(int i=0;i<=N;i++) {
    for(int j=0;j<=W;j++) {
        table[i][j]=0;
    }
}

🔍 执行过程

  1. 创建(N+1)行×(W+1)列的二维数组
  2. 初始化边界条件:
    • table[0][j] = 0(无物品可装)
    • table[i][0] = 0(无容量可用)
┌───────────────┐
│  Start Init  │
└───────┬───────┘
        │
┌───────▼───────┐
│ i=0 to N     │
├───────┬───────┤
│ j=0 to W     │
├───────▼───────┤
│ table[i][j]=0 │
└───────┬───────┘
        │
┌───────▼───────┐
│ End Init      │
└───────────────┘

2. 动态规划核心 dynamics()
for(int i=1;i<=N;i++) {          // 物品维度
    for(int j=1;j<=W;j++) {      // 容量维度
        // 不选当前物品
        table[i][j] = table[i-1][j]; 
        // 选当前物品(需容量足够)
        if(j >= w[i]) {
            table[i][j] = max(
                table[i][j], 
                table[i-1][j-w[i]] + v[i]
            );
        }
    }
}

📊 状态转移矩阵演变

迭代过程示例(i=2时):
  容量 j | 0 1 2 3 4 5
i=0     | 0 0 0 0 0 0
i=1     | 0 2 2 2 2 2 
i=2     | 0 2 max(2,2+4)=6 ...

完整流程图与时序图

系统级流程图

在这里插入图片描述

时序图


复杂度深度分析

时间复杂度

  • 双重循环:O(N*W) = 4×5 = 20次核心计算
  • 计算过程:
Σ(i=1→4) Σ(j=1→5) [1次比较 + 1次查询] = 4×5×2 = 40次操作

空间复杂度

  • 二维数组存储:O(N*W) = 5×6 = 30个存储单元
  • 空间消耗分解:
基础类型Integer × 30 = 30×4 bytes = 120 bytes

完整代码

public class Knapsack {

    /*
     * 假设有背包中可以最多可以装4个产品;背包承受的最大容量为5,求该背包最大的价值为多少
     * N:为物品数量
     * W:为背包容量
     * w[]:表示每一个产品容量
     * v[]:表示每一个产品的价值
     *
     * */
    static final Integer N =4;
    static final Integer W= 5;
    Integer[] w =new Integer[]{0,1,2,3,4};
    Integer[] v= new  Integer[]{0,2,4,5,6};
    private Integer[][] table = new  Integer[N+1][W+1];

    void  init(){
        for(int i=0;i<=N;i++){
            for(int j=0;j<=W;j++){
                table[i][j]=0;
            }
        }
    }
    void print(){
        for(int i=0;i<=N;i++){
            for(int j=0;j<=W;j++){
                System.out.print(table[i][j]+"   ");
            }
            System.out.println();
        }
    }
    void dynamics(){
        for(int i=1;i<=N;i++){

            for(int j=1;j<=W;j++){

                table[i][j]=table[i-1][j]; // 不选第i个物品
                if(j>=w[i]){// 选第i个物品
                    table[i][j]=max(table[i][j],table[i-1][j-w[i]]+v[i]);
                }

            }
        }
    }
    // 判断大小的方法
    Integer max(Integer value1,Integer value2){
        return value1>value2?value1:value2;
    }


    public static void main(String[] args) {
        Knapsack k=new Knapsack();
        k.init();
        k.dynamics();
        k.print();





    }
}

结果截图:

扩展解法对比

1. 回溯法(决策树实现)
int backtrack(int i, int currentW, int currentV) {
    if(i > N) return currentV;
    if(currentW + w[i] > W) {
        return backtrack(i+1, currentW, currentV);
    }
    return max(
        backtrack(i+1, currentW, currentV),
        backtrack(i+1, currentW + w[i], currentV + v[i])
    );
}

⚠️ 问题规模达20时计算量超百万次

2. 空间优化DP(滚动数组)
int[] dp = new int[W+1];
for(int i=1; i<=N; i++){
    for(int j=W; j>=w[i]; j--){ // 逆序更新
        dp[j] = Math.max(dp[j], dp[j-w[i]] + v[i]);
    }
}

🔧 优势:空间复杂度降为O(W) = 6 units

3. 分支限界法(优先队列实现)
from queue import PriorityQueue

class Node:
    def __init__(self, level, weight, value, bound):
        self.level = level
        self.weight = weight
        self.value = value
        self.bound = bound

def bound(node):
    # 计算剩余物品的最大可能价值
    ...

算法选择策略

方法适用场景时间复杂度空间复杂度
标准动态规划中小规模精确计算O(N*W)O(N*W)
空间优化DP大规模数据处理O(N*W)O(W)
回溯法物品数<20O(2^N)O(N)
分支限界法需要快速近似解O(2^N)O(2^N)

完整代码执行结果
0   0   0   0   0   0   
0   2   2   2   2   2   
0   2   4   6   6   6   
0   2   4   6   7   9   
0   2   4   6   7   9   

最终最大价值为 9,通过物品选择(2+3号物品:重量2+3=5,价值4+5=9)实现


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode刷题SQL笔记

系列博客目录 文章目录 系列博客目录1.distinct关键字 去除重复2.char_length()3.group by 与 count()连用4.date类型有个函数datediff()5.mod 函数6.join和left join的区别1. **JOIN&#xff08;内连接&#xff0c;INNER JOIN&#xff09;**示例&#xff1a; 2. **LEFT JOIN&a…

循环神经网络 - 参数学习之随时间反向传播算法

本文中&#xff0c;我们以同步的序列到序列模式为例来介绍循环神经网络的参数学习。 循环神经网络中存在一个递归调用的函数 &#x1d453;(⋅)&#xff0c;因此其计算参数梯度的方式和前馈神经网络不太相同。在循环神经网络中主要有两种计算梯度的方式&#xff1a;随时间反向…

球类(继承和多态)

父类Ball&#xff0c;设置为抽象类&#xff0c;调用get和set方法创建对象&#xff0c;将子类重写的功能函数抽象化。 // 抽象球类 abstract class Ball {private String name;private double radius; // 半径private double weight; // 重量private double price; // 价格// 构…

DFS和BFS的模版

dfs dfs金典例题理解就是走迷宫 P1605 迷宫 - 洛谷 dfs本质上在套一个模版&#xff1a; ///dfs #include<bits/stdc.h> using namespace std; int a[10][10]{0}; int m,n,t,ans0; int ex,ey; int v[10][10]{0}; int dx[4]{-1,0,1,0}; int dy[4]{0,1,0,-1}; void dfs(in…

Ansible Playbook 进阶探秘:Handlers、变量、循环及条件判断全解析

192.168.60.100ansible.com192.168.60.110 client-1.com 192.168.60.120client-2.com192.168.60.130client-1.com 一、Handlers 介绍&#xff1a;在发生改变时执行的操作(类似puppet通知机制) 示例&#xff1a; 当apache的配置文件发生改变时&#xff0c;apache服务才会重启…

MATLAB的24脉波整流器Simulink仿真与故障诊断

本博客来源于CSDN机器鱼&#xff0c;未同意任何人转载。 更多内容&#xff0c;欢迎点击本专栏目录&#xff0c;查看更多内容。 目录 0 引言 1 故障数据采集 2 故障特征提取 3 故障诊断分类 4 结语 本博客内容是在MATLAB2023下完成。 0 引言 对于电力电子电路的故障诊断…

linux第三次作业

1、将你的虚拟机的网卡模式设置为nat模式&#xff0c;给虚拟机网卡配置三个主机位分别为100、200、168的ip地址 2、测试你的虚拟机是否能够ping通网关和dns&#xff0c;如果不能请修改网关和dns的地址 3、将如下内容写入/etc/hosts文件中&#xff08;如果有多个ip地址则写多行&…

国标GB28181视频平台EasyCVR顺应智慧农业自动化趋势,打造大棚实时视频监控防线

一、方案背景 近年来&#xff0c;温室大棚种植技术凭借其显著的优势&#xff0c;在提升农作物产量和质量、丰富农产品供应方面发挥了重要的作用&#xff0c;极大改善了人们的生活水平&#xff0c;得到了广泛的推广和应用。大棚内的温度、湿度、光照度和二氧化碳浓度等环境因素…

HOOPS Visualize:跨平台、高性能的三维图形渲染技术解析

在当今数字化时代&#xff0c;三维可视化技术已成为众多行业的核心竞争力。HOOPS Visualize作为一款功能强大的三维图形渲染引擎&#xff0c;凭借其卓越的渲染能力、跨平台支持、丰富的交互功能、高度定制化以及快速部署等特性&#xff0c;为开发人员提供了构建高质量、高性能3…

蓝桥杯 C/C++ 组历届真题合集速刷(一)

一、1.单词分析 - 蓝桥云课 &#xff08;模拟、枚举&#xff09;算法代码&#xff1a; #include <bits/stdc.h> using namespace std;int main() {string s;cin>>s;unordered_map<char,int> mp;for(auto ch:s){mp[ch];}char result_charz;int max_count0;fo…

多类型医疗自助终端智能化升级路径(代码版.上)

大型医疗自助终端的智能化升级是医疗信息化发展的重要方向,其思维链一体化路径需要围绕技术架构、数据流协同、算法优化和用户体验展开: 一、技术架构层:分布式边缘计算与云端协同 以下针对技术架构层的分布式边缘计算与云端协同模块,提供具体编程实现方案: 一、边缘节点…

区间 DP 详解

文章目录 区间 DP分割型合并型环形合并 区间 DP 区间 DP&#xff0c;就是在对一段区间进行了若干次操作后的最小代价&#xff0c;一般是合并和拆分类型。 分割型 分割型&#xff0c;指把一个区间内的几项分开拆成一份一份的&#xff0c;再全部合起来就是当前答案&#xff0c…

QAM 信号的距离以及能量归一化

QAM星座图平均功率能量_星座图功率计算-CSDN博客 正交幅度调制(QAM) - Vinson88 - 博客园 不同阶QAM调制星座图中&#xff0c;符号能量的归一化计算原理_qpsk的星座图归一化-CSDN博客 https://zhuanlan.zhihu.com/p/690157236

Reactive编程框架与工具

文章目录 6.2 后端 Reactive 框架6.2.1 Spring WebFlux核心架构核心组件实际应用高级特性性能优化适用场景与限制 6.2.2 Akka&#xff08;Actor模型&#xff09;Actor模型基础基本用法高级特性响应式特性实现性能优化实际应用场景优势与挑战 6.2.3 Vert.x&#xff08;事件驱动&…

Python爬虫第7节-requests库的高级用法

目录 前言 一、文件上传 二、Cookies 三、会话维持 四、SSL证书验证 五、代理设置 六、超时设置 七、身份认证 八、Prepared Request 前言 上一节&#xff0c;我们认识了requests库的基本用法&#xff0c;像发起GET、POST请求&#xff0c;以及了解Response对象是什么。…

Maven的安装配置-项目管理工具

各位看官&#xff0c;大家早安午安晚安呀~~~ 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习&#xff1a;Maven的安装配置-项目管理工具 目录 1.什么是Maven&#xff1f;Maven用来干什么的&#xff1f…

智能 SQL 优化工具 PawSQL 月度更新 | 2025年3月

&#x1f4cc; 更新速览 本月更新包含 21项功能增强 和 9项问题修复&#xff0c;重点提升SQL解析精度与优化建议覆盖率。 一、SQL解析能力扩展 ✨ 新增SQL语法解析支持 SELECT...INTO TABLE 语法解析&#xff08;3/26&#xff09; ALTER INDEX RENAME/VISIBLE 语句解析&#…

Ubuntu虚拟机编译安装部分OpenCV模块方法实现——保姆级教程

Ubuntu虚拟机的安装过程可以查看另一篇文章&#xff1a;VMware安装Ubuntu虚拟机实现COpenCV代码在虚拟机下运行教程-CSDN博客 目前我们已经下载好了OpenCV&#xff0c;这里以OpenCV4.5.2为例。 在内存要求尽可能小的情况下&#xff0c;可以尝试只编译安装代码中使用到的OpenC…

spring mvc @ResponseBody 注解转换为 JSON 的原理与实现详解

ResponseBody 注解转换为 JSON 的原理与实现详解 1. 核心作用 ResponseBody 是 Spring MVC 的一个注解&#xff0c;用于将方法返回的对象直接序列化为 HTTP 响应体&#xff08;如 JSON 或 XML&#xff09;&#xff0c;而不是通过视图解析器渲染为视图&#xff08;如 HTML&…

skynet.rawcall使用详解及应用场景

目录 核心特性函数原型使用场景场景 1&#xff1a;高性能二进制传输&#xff08;如文件转发&#xff09;场景 2&#xff1a;自定义序列化协议&#xff08;如 Protocol Buffers&#xff09;场景 3&#xff1a;跨服务共享内存&#xff08;避免拷贝&#xff09; 配套接收方实现与 …