算法训练营Day42(背包问题)

基础

非竞赛只需要搞懂0-1背包和完全背包

0-1背包基础

0-1背包是完全背包和多重背包的基础

n个物品,每个物品一个,每个物品有自己的重量和价值,,一个背包能装m物品,问最多装多少物品。

暴力解法,n个物品,2^n

dp数组:

可以二维,也可以优化成一维

二维

dp[i][j]:  0-i的0物品任选一个放到背包j中,价值总和最大是多少

递推公式

dp[i][j]

不放物品i,,物品是 i 背包为j,最大价值,

        dp[i-1][j]:不放物品i的最大价值。

放物品i: 物品为i-1{代表从0到i-1中选物品,所以物品i已经被放到背包}          

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

        {i-1代表0到i个物品,去掉i, 

         j-weight[i]{代表物品i放入背包,剩下的重量为这个}

        value[i]   :物品的价值

        dp[i-1][j-weight[i]]代表放入物品i,剩下物品的最大价值

        两者相加就是当前背包的最大价值。

物品只有放与不放,所以递推公式:

        dp[i][j] = Math.max(dp[i-1][j],Math.max(dp[i-1][j-weight[i]+value[i]))

初始化

dp[i][j]由上面{dp[i-1][j]}推除,或者左上角推出

还是初始化第一列和第一行

背包容量为0的时候,什么也不能放了,物品0到i都是初始化为0

第一行,这个要初始化的时候要看物品0的重量,如果为3

那么3 4这两个要初始化成value[0]

也就是weight[0]到i初始化成value[0]

遍历顺序

先遍历哪个都可以,因为从左上和上遍历,这两个都可以通过递推公式遍历完

代码

public class BagProblem {public static void main(String[] args) {int[] weight = {1,3,4};int[] value = {15,20,30};int bagSize = 4;testWeightBagProblem(weight,value,bagSize);}/*** 动态规划获得结果* @param weight  物品的重量* @param value   物品的价值* @param bagSize 背包的容量*/public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){// 创建dp数组int goods = weight.length;  // 获取物品的数量int[][] dp = new int[goods][bagSize + 1];// 初始化dp数组// 创建数组后,其中默认的值就是0for (int j = weight[0]; j <= bagSize; j++) {dp[0][j] = value[0];}// 填充dp数组for (int i = 1; i < weight.length; i++) {for (int j = 1; j <= bagSize; j++) {if (j < weight[i]) {/*** 当前背包的容量都没有当前物品i大的时候,是不放物品i的* 那么前i-1个物品能放下的最大价值就是当前情况的最大价值*/dp[i][j] = dp[i-1][j];} else {/*** 当前背包的容量可以放下物品i* 那么此时分两种情况:*    1、不放物品i*    2、放物品i* 比较这两种情况下,哪种背包中物品的最大价值最大*/dp[i][j] = Math.max(dp[i-1][j] , dp[i-1][j-weight[i]] + value[i]);}}}// 打印dp数组for (int i = 0; i < goods; i++) {for (int j = 0; j <= bagSize; j++) {System.out.print(dp[i][j] + "\t");}System.out.println("\n");}}
}

0-1背包-一维数组

压缩原理

因为每一层都是由上一层得到的,所以可以先拷贝到,通过滚动数组的形式实现原地修改!

dp数组含义

dp[j]       :  容量为j时,背包最大价值为dp[j]

递推公式

不放物品i,因为这个数组是上一层拷贝下来的,上一层比如,物品1,那么这一层是物品2,直接拷贝下来,是不包含物品2的,

所以不妨物品i   :容量为j时,背包的最大价值就是dp[j]  {也就是抛去物品i的最大价值}

放物品i时:  

        容量肯定要编程j-weight[j]的,现在放物品i,当前逻辑就要加上i的价值value[i]

        {{{其实从最开始,初始化,后面价值的总和都是加这个value[i]得到的

        所以最大价值时dp[j-weight[i]] 

所以递推公式为:

        dp[j] = Math.max(dp[j],dp[j-weight]+value[i]){物理上就是数组当前位置和左面-weight位置}

初始化

容量为0 那么价值肯定0

所以初始化,dp[0]=0;

非0 的话,会被覆盖,默认为0就可

遍历顺序

现在数组是上一层的结果,想要倒叙遍历得到才是正常的计算

代码

 public static void main(String[] args) {int[] weight = {1, 3, 4};int[] value = {15, 20, 30};int bagWight = 4;testWeightBagProblem(weight, value, bagWight);}public static void testWeightBagProblem(int[] weight, int[] value, int bagWeight){int wLen = weight.length;//定义dp数组:dp[j]表示背包容量为j时,能获得的最大价值int[] dp = new int[bagWeight + 1];//遍历顺序:先遍历物品,再遍历背包容量for (int i = 0; i < wLen; i++){for (int j = bagWeight; j >= weight[i]; j--){dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);}}//打印dp数组for (int j = 0; j <= bagWeight; j++){System.out.print(dp[j] + " ");}}

416. 分割等和子集

416. 分割等和子集 - 力扣(LeetCode)

class Solution {public boolean canPartition(int[] nums) {if(nums == null || nums.length == 0) return false;int sum = 0;for(int num : nums) {sum += num;}if(sum%2!=0) return false;int target = sum/2;//dp数组 :含义:容量为j时,最大价值为dp[j]int [] dp = new int[target+1];//初始化//默认为0即可//遍历顺序//先遍历物品for(int i = 0;i<nums.length;i++){for(int j = target;j>=nums[i];j--){//递推公式dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);}}return dp[target] == target;}}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【c++】list迭代器失效问题

目录 一、list iterator的使用 二、list的迭代器失效 一、list iterator的使用 对于list的迭代器的用法&#xff0c;可以将它看做一个指针&#xff08;实际要更加复杂&#xff09;来使用&#xff0c;该指针指向list中的一个节点。 【注意】 (1)begin和end为正向迭代器&#x…

深度解析Cron表达式:精确控制任务调度的艺术

深度解析Cron表达式&#xff1a;精确控制任务调度的艺术 希望我们都可以满怀期待的路过每一个转角 去遇见 那个属于自己故事的开始 去追寻那个最真实的自己 去放下 去拿起 安然&#xff0c;自得&#xff0c;不受世俗牵绊… 导言 在计算机科学领域&#xff0c;任务调度是一项关…

qt初入门3:文件,目录,临时文件,监视相关demo

参考qt的书籍demo&#xff0c;做练习 目录和文件相关操作&#xff1a; QCoreApplication类 主要处理获取app所在目录&#xff0c;路径&#xff0c;app名称&#xff0c;lib库路径等。 QFile类 主要实现文件拷贝&#xff0c;校验存在&#xff0c;删除&#xff0c;重命名&#xf…

NIO通信代码示例

NIO通信架构图 1.Client NioClient package nio;import constant.Constant;import java.io.IOException; import java.util.Scanner;public class NioClient {private static NioClientHandle nioClientHandle;public static void start() {nioClientHandle new NioClientHa…

面试算法115:重建序列

题目 长度为n的数组org是数字1&#xff5e;n的一个排列&#xff0c;seqs是若干序列&#xff0c;请判断数组org是否为可以由seqs重建的唯一序列。重建的序列是指seqs所有序列的最短公共超序列&#xff0c;即seqs中的任意序列都是该序列的子序列。 例如&#xff0c;如果数组org为…

Element|Upload结合Progress实现上传展示进度条

背景 &#xff1a; 项目里的 附件上传 题型组件&#xff0c;用户在上传过程中&#xff0c;如果文件较大&#xff0c;上传过程较慢&#xff0c;而又没有一个类似 Loading... 的加载过程的话&#xff0c;会显得干愣愣的&#xff0c;用户体验较差&#xff0c;所以需要添加一个进度…

Day4Qt

1.头文件: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTime>//时间类 #include <QTimer>//时间事件类 #include <QTimerEvent>//定时器类 #include <QTextToSpeech> namespace Ui { class Widget; }class Widget : publi…

OpenCV C++ 图像处理实战 ——《多尺度自适应Gamma矫正的低照图像增强》

OpenCV C++ 图像处理实战 ——《多尺度自适应Gamma矫正的低照图像增强》 一、结果演示二、多尺度自适应Gamma矫正的低照度图像增强2.1HSI颜色空间2.1.1 功能源码2.2 自适应于直方图分布的 Gamma 矫正2.2.1 功能源码2.3 多尺度 Retinex 分解与明度增强2.3.1 功能源码三、源码测试…

性能测试之Mysql数据库调优

一、前言 性能调优前提&#xff1a;无监控不调优&#xff0c;对于mysql性能的监控前几天有文章提到过&#xff0c;有兴趣的朋友可以去看一下 二、Mysql性能指标及问题分析和定位 1、我们在监控图表中关注的性能指标大概有这么几个&#xff1a;CPU、内存、连接数、io读写时间、…

x-cmd pkg | grex - 用于生成正则表达的命令行工具

目录 简介首次用户生成的正则表达式与 perl 和 rust 兼容支持 Unicode 符号友好的用户体验进一步阅读 简介 grex 是一个旨在简化创作正则表达式的复杂且繁琐任务的库和命令行程序。这个项目最初是 Devon Govett 编写的 JavaScript 工具 regexgen 的 Rust 移植。但 regexgen 在…

鸿蒙开发已解决-arkts编译报错-arkts-limited-stdlib错误

文章目录 项目场景:问题描述原因分析:解决方案:适配指导案例此Bug解决方案总结项目场景: arkts编译报错-arkts-limited-stdlib错误。 我用Deveco studio4.0 beta2开发应用,报arkts-limited-stdlib错误 报错内容为: ERROR: ArKTS:ERROR File: D:/prRevivw/3792lapplica…

SPI接口协议

SPI接口协议 SPI(Serial Peripheral Interface)是由Motorola公司定义的接口协议标准&#xff0c;串行外设接口(SPI)是微控制器和外围IC&#xff08;如传感器、 ADC、 DAC、移位寄存器、 SRAM等&#xff09;之间使用最广泛的接口之一。SPI是一种同步、全双工、主从式接口&#x…