首页 > 其他分享 >luogu4_dp

luogu4_dp

时间:2023-07-13 20:12:51浏览次数:43  
标签:.. 容量 bound vt luogu4 ans 物品 dp

背包问题、线性动归、多维动归、技巧与记忆化
《背包问题九讲》

背包九讲

01\完全\多重\混合

  • 01(每个物品仅1个 总容量V不用装满)

    for i=1..n
      	for j=V..v[i]
      			ans[j]=max(ans[j],ans[j-v[i]]+w[i]);
    
  • 完全(商品可多次取)

    for i=1..n
      	for j=v[i]..V //区别在此
      			ans[j]=max(ans[j],ans[j-v[i]+w[i]]);
    
  • 多重(有1个的有n个的)

  • 混合

二维费用

2种总容量。每个物品2种费用、2种价值。用二维数组即可。

分组的背包

物品被划分为若干组。每个组之间物品相互冲突,最多选1件。

for 所有的组k
		for j=V..0
    		for i=k里所有物品
    				f[j]=max(f[j],f[j-v[i]]+w[i]);

注意V层循环必须包裹i层

有依赖的背包

泛化物品

分组的背包问题

P1060 开心的金明

启蒙文章:https://www.luogu.org/blog/user21354/solution-p1060

  • 一维常数优化的bound啥意思

关于一维常数优化

看了几篇文章。终于自己理解出了常数优化的意思。主要是很多文章讲得迷迷糊糊,还有的给的方程是错的。要么就是w和v这种字母乱用文章也不解释清楚代表啥就放公式!

下面我来说说自己的理解。二维的情况就不说了。先看一维优化后代码是这样的:

总容量V 每个物品容量v[i] 每个物品价值w[i]

for i=1..n
	for j=V..v[i]//容量小于v[i]的肯定放不下v[i] 没必要更新
		ans[j]=max{ans[j],ans[j-v[i]]+w[i]}

核心思想:

思考,是不是整个循环跑下来。我们只不过是要个ans数组的最后一个元素。

假设总容量V=20.5个商品 我们不就想要个ans[20]吗?

那i=5时,是不是执行一次更新ans[20]就好了。没必要再更新ans[19]了吧?

假设第5个物品容量v[5]=3,我们是不是只需要ans[17]这个结果就行了?

在i=4的那层循环里,假设v[4]=3,那我只需要更新到ans[17-3]即ans[14]就可以了啊。因为有了ans[14],如果物4和5都需要被放进去。我们还有足够的6个空间放啊。

所以我们需要一个常数优化。尽可能地提高V的下界(这样更新的次数就少了)

看代码:

for i=1..n
  sumV-=v[i];//i个物品总容量和为sumV,减去第i个的v[i],就是剩下物品需要的容量和。只要更新到这里就足够后面的物品i+1到n全放进去的容量了。
	bound=max(v[i],V-sumV);//v[i]和V-sumV选一个最大的即可。如果比v[i]还小,第i个肯定放不进去,ans不必更新;如果比V-sumV还小更新了后面也用不到。就像刚刚说的,第5个商品只需要看ans[17]就可以了。ans[16]是多少都无所谓啊。我ans[17]里存的数肯定比你ans[16]还大。ans[16]在后面i的循环中也不可能被用到。
	for j=V..bound
			ans[j]=max(ans[j],ans[j-v[i]]+w[i]);

P1064 金明的预算方案

采用分组的思路。毕竟这题附件最多两个。可以枚举出4种情况。这四种情况就是一组。

然而枚举的方法毕竟不适合附件多的情况。看看别人的解法吧!

这题的小坑:

  • 附件编号是商品的总编号。由于我是分组存。要对总编号和我自己的分组编号做一个映射。
  • 权重是 价格*价值。

P1164** 小A点菜

  • 重刷标记!

P1048 采药P1616 疯狂的采药

采药就是基本的0-1背包。而疯狂的采药则是完全背包。

下面先看一下他们dp遍历的过程:

都采用一维数组优化,

输入数据为:容量m=20 物品数量n=3

分别是 ①v=50,w=100 ②v=15,w=1 ③v=1,w=2

第一个商品一定放不进去。我们不做讨论。主要看2、3

  • 0-1背包:容量m从20开始,循环条件m>=v[i].

    • i=2时,ans[20]~ans[15]都更新了。ans[14]循环停止。

    • i=3时,ans[20]=max(1,ans[20-1]+2)

      就是容量为19时的最大值1,加上第三个物品,更新最大值3

  • 完全背包:m从0开始到到20。

    • i=2时,一直到ans[15]才能放进去。

    划重点 看下面

    • i=3时,ans[1]=2, ans[2]=max(0,ans[1]+2)=max(0,4)=4

      看到没,容量为2时,最大值是容量为1时的,再放进去一个③。③被放了两次。这就是完全背包问题。

      记得用一维数组做。用二维的是ans[i][j]=ans[i-1]xxx,从状态转移方程上就限定了,第i个物品不会被多次存入。

P1049 装箱问题

水题。

线性动归

P1020 导弹拦截

最长不升序列和最短上升序列

好题!

需要注意的是lower/upper_bound这个方法:

  • 必须传入有序的数列,且根据排序规则传入一个compare方法
  • 返回值是一个指针,故 -vt.begin()得到的是数组下标,为什么会得到?肯定是因为重载了-

实例:

vector<int> vt = {1,2,2,2,3,4,5,6,7};
    auto p1 = lower_bound(vt.begin(),vt.end(),2)-vt.begin();//1 第一个2
    auto p2 = upper_bound(vt.begin(),vt.end(),2)-vt.begin();//4 3的位置
    
    //下面vt改成降序
    vt = {7,6,6,6,5,4,3,2,1};
    //最后传入的比较函数也应改成greater<int>()
    auto p3 = lower_bound(vt.begin(),vt.end(),6,greater<int>())-vt.begin();
    auto p4 = upper_bound(vt.begin(),vt.end(),6,greater<int>())-vt.begin();

可以理解为:在有序序列中插入一个元素a,lower_bound返回的是能插入的最小的坐标,upper返回的是最大的坐标。

多维动归

技巧与记忆化

标签:..,容量,bound,vt,luogu4,ans,物品,dp
From: https://www.cnblogs.com/xuanshan/p/17551995.html

相关文章

  • 【DP】DMOPC '21 Contest 8 P5 - Tree Building
    ProblemLink给定\(n,m\)和一个长为\(m\)的代价序列,对于一棵\(n\)个节点,每个节点度数不超过\(m\)的树,定义它的代价为\(\sum\limits_{i=1}^na_{deg_i}\)。求代价最小的树的代价。\(n\le10^9,m\le3000,1\lea_i\le10^9\)。首先一眼变成选出\(n\)个\(a\)的和为......
  • 【学习笔记】插头 DP
    插头DP,是一类解决网格图上连通性问题的状压DP。相关概念轮廓线:已经决策的方格和未决策方格之间的分界线。插头:用来描述连通性,一个方格与其某一方向的相邻方格连通,则称这个方格有某个方向的插头。容易发现在轮廓线上,每个时刻都是有\(n\)个上插头与\(1\)个左插头。如图,红......
  • 动态规划DP入门笔记
    动态规划以斐波那契数列为例:\(f_i\)状态\(f_i=f_{i-1}+f_{i-2}\)转移方程\(f_0=0\),\(f_1=1\)初始化dp的实现方法一般有三种,其中的两种(最重要的)如下#include<bits/stdc++.h>usingnamespacestd;intf[200010];signedmain(){ intn; scanf("%d",&n);......
  • P1002 [NOIP2002 普及组] 过河卒 入门级别的dp
     思路:1.标记马点z[i][[j]=02.正常z[i][j]=z[i-1][j]+z[i][j-1]#include<iostream>usingnamespacestd;intn,m,a,b;longlongma[30][30],bck[30][30];intdx[8]={-2,-1,1,2,2,1,-1,-2},dy[8]={1,2,2,1,-1,-2,-2,-1};voidcan_not_reach(intx,inty){ma[......
  • 【网络面试题】你知道 TCP 和 UDP 区别吗?
    ......
  • Ubuntu资源暂时不可用 E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源
    ubuntu使用apt时出现Ubuntu资源暂时不可用E:无法获得锁/var/lib/dpkg/lock-frontend-open(11:资源暂时不可用)一般是已经存在apt进程占用了,通过ps-grep查看ps-grep|apt查到相关进程后通过kill删掉kill-93298kill-93302再依次执行下面命令sudorm/var/cache......
  • RDP远程桌面凭证获取密码
    参考链接:https://blog.csdn.net/qq_36618918/article/details/130677478使用的工具:mimikatz前言该方式适用于获取系统存储的凭证中的用户名和密码,不仅限于远程桌面的凭证。使用的工具是mimikatz,杀软会报毒拦截,下载及使用的时候可以推出杀软下载地址:https://gitcode.net/mi......
  • 【学习笔记】空空的浅谈DP
    特邀讲师:墨染空洛谷用户@Remakedalao博客中的学习笔记:https://www.cnblogs.com/dmoransky/p/14063918.htmlDP1决策单调性1.2由已知量转移:分治算法洛谷P3515:[POI2011]LightningConductor1.3由之前状态转移:单调栈上二分洛谷P1912:[NOI2009]诗人小G\(f......
  • 单调栈与单调队列优化 dp
    单调栈将一个元素插入单调栈时,为了维护栈的单调性,需要在保证将该元素插入到栈顶后整个栈满足单调性的前提下弹出最少的元素。例如,栈中自顶向下的元素为\(\{0,11,45,81\}\)。插入元素\(14\)时为了保证单调性需要依次弹出元素\(0,11\),操作后栈变为\(\{14,45,81\}\)。模板......
  • DDP学习笔记
    概念DDP,可以理解为转移会发生改变的动态规划。当然这个改变是题目中给的,包括系数,转移位置的改变。显然暴力枚举这些改变是不现实的,我们要把改变体现到其他地方。最经典的,体现到矩阵上。我们把转移写成矩阵,那么改变转移就是改变转移矩阵。具体的改变会落实到具体的题目上。广......