当前位置: 首页 > article >正文

数据结构和算法-01背包问题01-认识01背包

0-1背包

什么是0-1背包问题?

[0-1背包问题Knapsack Problem] 假设有一个背包,可承载的最大重量是W(kg), 现在有n个物品,每个物品的重量不等, 并且不可分割。我们期待选择几件物品放入背包中,在不超过背包最大承载重量的前提下,如何让背包中的物品总重量最大?

image-20241029092409759

回溯法

分析

 int capacity = 4;
 int[] weight = {2, 1, 3};
 int[] val = {4, 2, 3};

image-20241029153702115

参考实现

import java.util.List;

public class Knapsack {

    private final int[] weight;
    private final int[] val;
    private final int capacity; //背包容量(最大承载)
    private final int n; //物品数量
    private int perfectValue; //最大价值


    public Knapsack(int[] weight, int[] val, int capacity) {
        this.weight = weight;
        this.val = val;
        this.capacity = capacity;
        this.n = weight.length;
    }

    public int getPerfectValue() {
        return perfectValue;
    }

    public void dfs(int depth, int sumWeight, int sumVal) {
        if (depth == n) { //当前路径搜索完毕
            if (sumVal > perfectValue) {
                perfectValue = sumVal;
            }
            return;
        }
        if (sumWeight + weight[depth] <= capacity) {//总重+当前重量<=最大载重
            visited[depth] = true;
            dfs(depth + 1, sumWeight + weight[depth], sumVal + val[depth], visited);
            visited[depth] = false;
        }
        dfs(i + 1, sumWeight, sumVal);//不选择
    }


    public static void main(String[] args) {
        int[] weight = {2, 1, 3};
        int[] val = {4, 2, 3};
        int capacity = 4;

        Knapsack oOne = new Knapsack(weight, val, capacity);
        oOne.dfs(0, 0, 0);
        System.out.println(oOne.getPerfectValue());

    }
}

动态规划法

分析

在考虑第n个物品时,有两种状态需要考虑。

image-20241029150249669

将第n个物品不放入背包

tips: 物品数量是从0开始, n个物品则为n-1

当前物品的最大价值 = 已经放入背包中物品的最大价值

dp[n-1][c]
将第n个物品放入背包

如果放入背包,那么当前物品的价格 = 之前物品的价值+ 剩余容量物品的价值。

dp[n-1][c-weight[n-1]]+vals[n-1])

参考实现

package com.ffyc.dp;

public class KnapackDp {

    public int knapack(int[] weight, int[] vals, int capacity) {
        final int W = weight.length;
        int[][] dp = new int[W+1][capacity+1];

        for(int n = 1; n <= W;n++){
            for(int c = 1; c <= capacity;c++){
                if(weight[n-1] < c){
                    dp[n][c]= Math.max(dp[n-1][c],
                            dp[n-1][c-weight[n-1]]+vals[n-1]);
                }
            }
        }
        return dp[W][capacity];

    }

    public static void main(String[] args) {
        int[] weight = {2, 1, 3};
        int[] val = {4, 2, 3};
        int capacity = 4;
        System.out.println(new KnapackDp().knapack(weight, val, 4));
    }
}


http://www.kler.cn/a/383518.html

相关文章:

  • 【Linux】Pinctrl子系统和GPIO子系统
  • 【WebRTC】视频采集模块流程的简单分析
  • MinGW-w64_10.0.0 + GCC12_x86_64-12.2.0-release-posix-seh-msvcrt-rt_v10-rev2.zip
  • 某华迪加现场大屏互动系统mobile.do.php任意文件上传
  • [HCTF 2018]WarmUp 1--详细解析
  • dns服务器配置
  • SpringBoot健身房管理:现代化技术解决方案
  • 如何使用闲置硬件搭建一个安装运行资源较少的Tipask问答网站服务器
  • 如何安全地使用反射API进行数据操作
  • NLP segment-03-基于 TF-IDF 实现关键词提取 java 开源实现
  • 【无标题】123
  • Web Components 是什么
  • 少儿编程教育的多维度对比:软件类、硬件类与软硬件结合课程的选择
  • 【网易云插件】听首歌放松放松
  • Oracle视频基础1.4.5练习
  • sdm845(oneplus6)的开机变砖(启动漰溃)ramdump被开源git仓库linux-ramdump-parser-v2提交3e7f37-正确解析
  • 代码随想录训练营Day19 | 39. 组合总和 - 40.组合总和II - 131.分割回文串
  • OpenCV视觉分析之目标跟踪(8)目标跟踪函数CamShift()使用
  • 【RESP问题】RESP.app GUI for Redis 连接不上redis服务器
  • AI - 使用LangChain请求LLM结构化生成内容
  • Unet++改进3:添加NAMAttention注意力机制
  • 重新回顾反向传播与梯度下降:训练神经网络的基石
  • Redis安装配置及基本使用(保姆级安装教程非常耐用)
  • 【云原生开发】K8S多集群资源管理平台架构设计
  • 【静态页面】尚品汇 1、设计稿分析及资源准备
  • Nginx 在中小企业的初级应用实操指南