背包问题(1)------动态规划

news2024/11/18 1:44:52

你有一个背包,地上一堆物品,挑选一些物品放入背包中,最大能够挑选出来的价值是多少

背包可以装满,背包也是可以不必都装满

 一)01背包问题

【模板】01背包_牛客题霸_牛客网 (nowcoder.com)

1)求这个背包最多可以装多大价值的物品?

那么这意味着这个背包可以不用完全装满,那么所能够装的最大价值就是10+4=14,此时装的容量是3,剩余背包容量体积是2

2)若背包恰好装满,求至多可以装多大价值的物品?

如果这个背包恰好装满,那么只能选择2物品和3号物品进行装上,此时装的物品的价值是9,背包剩余容量是0,如果无法将背包装满,就比如说在示例2中,那么返回0

第一问:

一)确定一个状态表示:经验+题目要求

1)背包问题本质上是一个线性的dp问题,当我们在挑选物品的时候,可以从左向右顺序进行挑选,考虑每一个物品是否挑选,从而放到背包里面

dp[i]表示从第一个物品开始进行挑选,挑选到第i个物品的时候所有的选择方法中最大的价值

2)在进行挑选dp[i]的时候是很有可能会使用到之前的状态的,我在进行填写dp[i]的时候,会进行考虑这个i号物品是否进行选择,必须得知道背包容量,不知道背包容量,所以不知道是否可以把物品放进背包;

3)dp[i][j]表示从前i个物品进行挑选,此时体积不超过j的(可以等于j也可以小于j),在这些选法中,所能进行挑选的最大价值,可以等于j也可以小于j

二)根据状态表示推导状态转移方程:根据最后一个位置的状况来进行划分问题:

1)要么我选择第i号位置的物品,要么我不进行选择第i号位置的物品

不选择i物品:dp[i][j]=dp[i-1][j],我们直接在1-i-1物品中找到最大价值,并且体积不超过j

选择i物品:dp[i][j]=w[i]+dp[i-1][j-v[i]] 

2)在两种情况中选择一个一个最大值即可,但是此时还需要考虑一个特殊情况,那么有可能是j-v[i]不存在,如果说背包的体积就是10,但是当前物品的体积是11,整个背包都装不下,所以一定要满足j-v[i]是大于等于0的;

3)假设j==v[i]那么dp[i][j]=w[i]

三:初始化+填表顺序+返回值:

1)下标从1开始进行计数,那么原始的dp表就多了一行和多了一列,第一行是0表示没有商品(有包没有能力装任何商品),第一列表示背包的容量是0(商品都装不进去),所以第一行和第一列都是0

2)从上向下填写,每一行从左向右进行填写

3)返回值:返回的是从N个物品中选择,总体积不超过V的商品所有选法中的最大价值

第二问:

一)定义一个状态标识:必须要装满

dp[i][j]表示从前i个物品中进行挑选,总体积此时正好等于j,所有选法中,所能进行挑选物品的最大价值

二)根据状态标识推导状态转移方程:

1)如果选择i位置的商品,那么就去1-i-1中去选择商品组合,选择商品总容量的总体积要等于j-v[i],如果当前礼物的价值已经超过了j(v[i]>j]那么一定不能选择当前商品,如果j==v[i],那么礼物的最大价值就是dp[i][j]=dp[i-1][j-v[i](j-v[i]>=0)

2)如果不选择i位置的商品,那么就去1-i-1中去寻找商品组合,dp[i][j]=dp[i-1][j],但是这个只是不一定存在的,我们可能永远也无法选取到总体积等于j的商品组合,如果dp[i][j]=-1的时候无法选择,总体积是无法凑到j的,但是这个dp[i-1][j]一定存在吗,我的意思是从前i-1个位置的物品进行挑选,选择体积恰好等于j的商品的最大价值,但是有可能选择不到,如果选择不到,那么就让dp[i-1][j]==-1

3)那么为什么不选择dp[i][j]=0来表示从前i个物品中进行挑选,总体积凑不到j的这种情况呢

dp[0][j]表示没有物品进行选择总体积等于j,此时能够选择到的商品的最大价值,其实是可以选到的,不过里面的价值是等于0;

4)对于第一种情况来说,我不进行选择i位置的元素,dp[i-1][j]如果等于-1,那么dp[i][j]=dp[i-1][j]也是可以的

5)对于第二种情况来说,如果选择i位置的商品,必须要进行判断dp[i-1][j-v[i]]不等于-1,如果在i-1区间内找不到礼物价值是j-v[i]的礼物组合,那么dp[i][j]也是-1

 三)初始化:

dp[0][0]=0,dp[0][i]=-1,dp[j][0]=0(啥都不选就可以了)

import java.util.Scanner;
import java.util.Arrays;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
      Scanner scanner=new Scanner(System.in);
      int n=scanner.nextInt();//物品的个数
      int V=scanner.nextInt();//背包的体积
      int[] v=new int[n+1];//存放物品的体积
      int[] w=new int[n+1];//存放物品的价值
      //让数组从第一个位置开始进行输入,到时候下标就不用-1了
      for(int i=1;i<=n;i++){
        v[i]=scanner.nextInt();
        w[i]=scanner.nextInt();
      }
    int[][] dp1=new int[n+1][V+1];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=V;j++){
           if(j-v[i]>=0) 
           dp1[i][j]=dp1[i-1][j-v[i]]+w[i];
            //如果不进行选择当前i位置的物品放入到背包里面
           dp1[i][j]=Math.max(dp1[i][j],dp1[i-1][j]);
           //如果选择当前i位置的物品放入到背包里面
        }
     }
    int[][] dp2=new int[n+1][V+1];
    dp2[0][0]=0;
    for(int i=1;i<=V;i++) dp2[0][i]=-1;
    //此时一件商品都没有,是无法找到一个商品使背包的体积变成j的
    //for(int i=1;i<=V;i++) dp2[i][0]=0;//此时啥也不选,就能使背包的体积变成0
 for(int i=1;i<=n;i++){
 for(int j=1;j<=V;j++){
   if(j-v[i]>=0&&(dp2[i-1][j-v[i]]!=-1))
           dp2[i][j]=dp2[i-1][j-v[i]]+w[i];
    else  dp2[i][j]=-1;
            //如果不进行选择当前i位置的物品放入到背包里面
           dp2[i][j]=Math.max(dp2[i][j],dp2[i-1][j]);
           //如果选择当前i位置的物品放入到背包里面
        }
 }
System.out.println(dp1[n][V]); 
System.out.println(dp2[n][V]==-1?0:dp2[n][V]); 
//如果最后无法凑出体积是V的情况,那么dp[n][V]是等于-1,那么dp[n][V]=0
    }   
}

四)利用滚动数组做空间上面的优化+直接在原始的代码上稍加修改即可

我们的dp[i][j]所依赖的是两部分的值dp[i][j]所进行依赖的是dp[i-1][j]和dp[i][j-v[i]],当我们在进行填写dp[i][j]的时候,只是需要dp[i-1]和dp[i][j-v[i]]的值即可,至于其他的值我是不会关心的

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

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

相关文章

Java编程实现遍历两个MAC地址之间所有MAC的方法

Java编程实现遍历两个MAC地址之间所有MAC的方法 本文实例讲述了java编程实现遍历两个MAC地址之间所有MAC的方法。分享给大家供大http://家参考&#xff0c;具体如下&#xff1a; 在对发放的设备进行后台管理时,很多时候会用到设备MAC这个字段,它可以标识唯一一个设备。然而在数…

【Axure高保真原型】图片放大镜效果

今天和大家分享图片放大镜效果的原型模板&#xff0c;鼠标移入图片区域后&#xff0c;会显示放大的方框&#xff0c;方框会跟随图片移动&#xff0c;右侧会显示方框区域的大图&#xff0c;具体效果可以观看下方视频或者打开预览地址体验。 【原型效果】 【Axure高保真原型】图…

一文详解Spring Bean循环依赖

一、背景 有好几次线上发布老应用时&#xff0c;遭遇代码启动报错&#xff0c;具体错误如下&#xff1a; Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name xxxManageFacadeImpl: Bean with name xxxManageFa…

centos7搭建airflow2.6.3教程

一、环境说明&#xff1a; python3.9.6mysql5.7数据库 基础环境自行安装&#xff0c;本教程不包含基础环境部分 二、安装airflow2.6.3 1.安装Linux系统依赖模块 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel…

PSP - 使用 MMseqs2 工具快速搜索蛋白质序列数据库 (GMGC)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131934642 MMseq2 是非常强大和高效的生物信息学软件&#xff0c;可以在极短的时间内对大规模的核苷酸和蛋白质序列进行搜索和聚类。主要特点有&a…

【2022】贝壳找房秋招C++工程师笔试卷1

题解&#xff1a;直接暴力 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param s string字符串 * param k int整型 * return string字符串*/string NS_String(string s, int k) {// writ…

【C语言day07】

在调用函数的时候&#xff0c;真实传递给函数的是实参&#xff0c;函数定义部分函数名后的参数是形参。 形参和实参的名字是可以相同的&#xff0c;在函数调用的时候&#xff0c;形参是实参的一份临时拷贝&#xff0c;分别占用不同的内存空间&#xff0c;所以A正确&#xff0c;…

智慧园区电力监控解决方案

1、概述 电力监控系统实现对园区变电站、配电房内断路器、变压器、柴油发电机以及其它重要设备进行监视、测量、记录、报警等功能&#xff0c;并与保护设备和远方控制中心及其他设备通信&#xff0c;实时掌握园区变电站和配电房运行状况&#xff0c;快速排除故障&#xff0c;保…

[UE4][C++]调整分屏模式下(本地多玩家)视口的显示位置和区域

一、分屏模式设置 在UE4中&#xff0c;多个玩家共用一个显示器就可以启用分屏模式&#xff0c;按玩家人数&#xff08;最大四人&#xff09;将屏幕均匀分割&#xff0c;显示不同玩家的视角&#xff0c;开发者可以在编辑器里设置分割类型&#xff08;水平或者垂直&#xff09;&a…

EC200U-CN学习(二)

EC200U系列内置丰富的网络协议&#xff0c;集成多个工业标准接口&#xff0c;并支持多种驱动和软件功能&#xff08;适用于Windows 7/8/8.1/10、Linux和Android等操作系统下的USB驱动&#xff09;&#xff0c;极大地拓展了其在M2M领域的应用范围&#xff0c;如POS、POC、ETC、共…

XCP详解「3.4·CANape中新建A2L文件」

返回 XCP详解「总目录」 A2L正常由ASAP2软件生成&#xff0c;但CANape也可以生成&#xff0c;此方法仅作知晓&#xff0c;不推荐使用 CANape新建工程后&#xff0c;新建Device&#xff0c;后面默认next next next 选择通道&#xff0c;设置网络参数&#xff08;波特率&#xf…

Vue - 可视化用户角色、菜单权限、按钮权限配置(动态获取菜单路由)

GitHub Demo 地址 在线预览 前言 关于动态获取路由已在这里给出方案 Vue - vue-admin-template模板项目改造&#xff1a;动态获取菜单路由 这里是在此基础上添加了系统管理模块&#xff0c;包含用户管理&#xff0c;角色管理&#xff0c;菜单管理&#xff0c;字典管理&#xf…

使用分布式HTTP代理爬虫实现数据抓取与分析的案例研究

在当今信息爆炸的时代&#xff0c;数据已经成为企业决策和发展的核心资源。然而&#xff0c;要获取大规模的数据并进行有效的分析是一项艰巨的任务。为了解决这一难题&#xff0c;我们进行了一项案例研究&#xff0c;通过使用分布式HTTP代理爬虫&#xff0c;实现数据抓取与分析…

【方法】带密码的ZIP分卷压缩文件如何解压?

当文件比较大的时候&#xff0c;很多人会在压缩时使用分卷压缩&#xff0c;这样可以将一个大文件分割成若干小分卷&#xff0c;方便保存及传输&#xff0c;也能减少下载时间。 如果分卷压缩文件设置了密码&#xff0c;要如何解压呢&#xff1f;下面小编以常用的ZIP格式为例&am…

IIS部署安装.NET CORE6.0应用程序,成功解决http error 503.the service is unavailable错误

一、下载安装.NET CORE 运行环境包 网址&#xff1a;Download .NET Core 3.1 (Linux, macOS, and Windows).NET Core 3.1 downloads for Linux, macOS, and Windows. .NET is a free, cross-platform, open-source developer platform for building many different types of ap…

Ubuntu--科研工具系列

翻译系列 pot-desktop github链接: https://github.com/pot-app/pot-desktop 下载deb Releases pot-app/pot-desktop GitHub 安装过程 在下载好的deb目录下打开终端(自动安装依赖) sudo apt install "XXX.deb" &#xff08;后面可以直接托文件到终端&#…

Redis集群的搭建

1.单机安装Redis 首先需要安装Redis所需要的依赖&#xff1a; yum install -y gcc tcl 然后将课前资料中提供的Redis安装包上传到虚拟机的任意目录&#xff1a; 例如&#xff0c;放到了/tmp目录&#xff1a; 解压缩&#xff1a; tar -xzf redis-6.2.4.tar.gz 解压后&#…

记一次杀猪盘的渗透之旅

所谓“杀猪盘”&#xff0c;是指诈骗分子利用网络交友通常是“异性”交友&#xff0c;诱导受害人下载诈骗APP并在上面进行各种“投资”&#xff0c;如菠菜、股票、期货甚至虚拟货币的网络诈骗。今年某月某日小白就遭遇了这种骗局&#xff0c;他先是被骗子通过QQ添加并下载了一个…

wireshark实战tcp三次握手和四次挥手

1 、安装好后wireshark后,由于我本地起了一个服务,所以我选择的是本地回环地址的这个选项,如下图(网络接口可以选择其它选项). 2、点击进去之后,在头部的栏上输入下面内容并且回车 ip.addr192.168.3.16 and tcp.port80803、浏览器发送请求 http://192.168.3.16:8080/tomcat_te…