队内第一次集训——基础DP(讲义篇)

2024-04-18 07:08

本文主要是介绍队内第一次集训——基础DP(讲义篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前比赛吃太多DP的亏了....好多题都看不出DP,还有的是看出来了但是动态转移方程推不出来,所以在此准备先恶补DP...


废话不多说,开始正题


DP其实就是,把一个大问题分解成若干子问题,通过解决若干子问题来获得最终结果,这样说起来有点像分治,但实际上并不是,因为DP需要每一步都保留目前的最优解,同时满足无后效性。无后效性就是过去已经考虑过的情况就不会对后面产生影响了,直接就不用理他们。通过每一步都保留当前最优解,来保证到最后的时候得到整个问题的最优解。

在这里主要讲解DP中最经典的入门题,背包问题

01背包

先简单介绍一下01背包。0和1分别代表着不取或者取这个物品。因为01背包问题通常是给你一个v体积的背包,然后给你i个物品,每个物品都有自己对应的体积和价值。然后问你如何放东西可以让背包的价值最大。


最最容易想到的当然是dfs,把所有情况都来一遍,可是在面对1e5的数据范围下,每种物品两种方式,那就相当于2^n次的巨无霸时间复杂度,是肯定要TLE的,所以这时候,DP就派上了用场。


DP是怎么看待这个问题的呢?首先回到概念本身,DP是将一个大问题分解成若干子问题。在这里,很明显就是分成每一个物品取或者不取。最优解又怎么理解呢?首先从二维数组的解法开始讲。dp[i][j]表示放到i个物品时,体积为j的情况下的背包最大价值是多少。刚开始所有dp数组对应的值都是0。然后放入第一个物品时,开始更新dp[1][j],如果j<物品的体积,也就意味着这个物品它放不进去,所以只能继承放0个物品的时候的最优解也就是0,到了>=j的时候,当然是放当前物品比较好,毕竟之前价值都是0,只要你能进去,你就是老大。所以这一次更新后,dp[1][j](0<j<v[i])还是0,放不进去没办法,剩下的都变成了第一个物品的价值。然后放入第二个物品,同样的,比自己体积小的时候,放不进去,那就看放一个的最好情况,就是当前的最好情况,谁叫自己放不进去只能靠第一个物品单打独斗呢..然后能放进去以后,就需要一番比较,这里咋比呢,就是比放入这个东西比较赚,还是不放入这个东西比较赚,不放入这个东西的价值很容易想到,就是p[1][j],现在开始放第二个物品了嘛,放之前的最好条件肯定是放第一个物品时候的情况。放入这个东西的价值呢?你想放入这个东西,前提就是,你有空间能放入这个东西,所以这里,就需要腾空一些体积放第二个物体,也就是a[1][j-v[i],放入一个物品的情况下,能放个第二个物品到达当前体积的体积就是我们需要的数据,看看这个时候,放入第二个物体好还是不放好。所以每过一个物品,当前dp都会存下放前面所有物品的最优解,所以以后都不用管前面放过的物品了,也就是所谓无后效性。


当然,二维数组,有一个维度还是放体积的,空间占用也太大了,如果有一道01背包题,不但体积大,而且数量多,如果用二维数组时间,肯定凉凉了,所以机智的人们又想到了一个牛B的办法,叫做滚动数组,在滚动数组的优化下,可以将二维数组压缩成一维。滚动数组的原理是什么呢?其实就是覆盖。仔细想想刚才我们的流程,是不是第i个物品,只需要考虑放完i-1个物品后的情况,再之前的因为无后效性根本就不用管了,放在那里浪费空间,所以我们需要的就是,更新这次以后,就不要过去的了,反正留着没用。那怎么做呢?先放一波代码:

for(int i=1;i<=n;i++){for(int j=v;j>=v[i];j--){dp[j]=max(dp[j],dp[j-v[i]]+c[i]);}
}

这是啥意思呢,i就是指放第几个物品,下面就是我们刚才说的那种覆盖,因为它判断的是当前的值或者dp[j-v[i]]+c[i]谁大,然而由于里面那层循环是从v到v[i],在回去的过程中,dp[j-v[i]]所对应的值没有被变过,一直是上一次更新的值,也就是dp[i-1][j-v[i]],所以就实现了我们需要的事情。

01背包初始化问题(完全背包和普通背包)

01背包如果前期dp全部初始化为0,那么就是不限定最终背包内容量的求最大价值,如果出了dp[0]=0,其他都是inf(无限大),那就是完全背包问题。

如何理解这个呢?

首先如果全是0,那么它可以从任意一个体积来推出当前状态,如果除了0都是inf,那么如果要更新值,一定是需要从0过来的,因为其他的无限大加价值比无限大还要大动不了,从0过来后不断更新,那些被更新的就是说踩在前物的基础上可以来到当前体积,那么dp[v]就是想到的值。


完全背包

完全背包就是说所有的物体都有无限个的时候背包最大价值是多少


如果二维实现就是先放一个该物体,再放俩,再放仨,直到背包全空都放不进这么多东西。其实完全背包你还要认识到一个本质问题,完全背包说是无限个物体,其实并不是纯粹的无限个物体,它是有限度的,也就是拼命塞该物体,一直到背包塞不下就停了,不是真的无限个在那里试。

这时候就要用一个很强的办法,也就是前面提到过的滚动数组。

单论代码两者特别相似,就只用把里面那层循环改成v[i]到v就可以了,为什么呢?因为你想,01背包的滚动数组实现,是因为dp[j-v[i]]始终是没改过的,如果是v[i]开始,那就是前面也被改了。如果背包够放两个了,由于前面已经被放一个更新了,你到该体积的时候判断的时候本身就是判断放两个会不会更好,也就是你这样遍历到v,就是能放多少该物体就放多少个看看会不会更好





这篇关于队内第一次集训——基础DP(讲义篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/914091

相关文章

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-

python操作redis基础

《python操作redis基础》Redis(RemoteDictionaryServer)是一个开源的、基于内存的键值对(Key-Value)存储系统,它通常用作数据库、缓存和消息代理,这篇文章... 目录1. Redis 简介2. 前提条件3. 安装 python Redis 客户端库4. 连接到 Re

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

Spring Boot集成SLF4j从基础到高级实践(最新推荐)

《SpringBoot集成SLF4j从基础到高级实践(最新推荐)》SLF4j(SimpleLoggingFacadeforJava)是一个日志门面(Facade),不是具体的日志实现,这篇文章主要介... 目录一、日志框架概述与SLF4j简介1.1 为什么需要日志框架1.2 主流日志框架对比1.3 SLF4

Spring Boot集成Logback终极指南之从基础到高级配置实战指南

《SpringBoot集成Logback终极指南之从基础到高级配置实战指南》Logback是一个可靠、通用且快速的Java日志框架,作为Log4j的继承者,由Log4j创始人设计,:本文主要介绍... 目录一、Logback简介与Spring Boot集成基础1.1 Logback是什么?1.2 Sprin

MySQL复合查询从基础到多表关联与高级技巧全解析

《MySQL复合查询从基础到多表关联与高级技巧全解析》本文主要讲解了在MySQL中的复合查询,下面是关于本文章所需要数据的建表语句,感兴趣的朋友跟随小编一起看看吧... 目录前言:1.基本查询回顾:1.1.查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J1.2.按照部门

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

mysql的基础语句和外键查询及其语句详解(推荐)

《mysql的基础语句和外键查询及其语句详解(推荐)》:本文主要介绍mysql的基础语句和外键查询及其语句详解(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录一、mysql 基础语句1. 数据库操作 创建数据库2. 表操作 创建表3. CRUD 操作二、外键