首页 > 其他分享 >单调队列优化多重背包

单调队列优化多重背包

时间:2023-11-21 21:03:27浏览次数:29  
标签:背包 队列 单调 优化 转移 dp

多重背包题目已经很熟了
我们要把它优化到O(nm)
也就是对于每一个物品,我们只能够对dp数组进行一次遍历,并且不能枚举取几个物品
或者说是,要在每一个状态下O(1)的找到取不同数量物品的最优解,并转移
我们可以发现,其实转移的区间是非常有规律的,f[j]只能够从f[j-v[i]],f[j-2*v[i]]....f[j-c[i]*v[i]]这几个状态转移
也就是一个有间隔的区间的最大值,如果区间范围是固定的,很明显是O(m)可以解决的
但是区间的范围是在单调的向左移动的,那就是对于每一个情况开一个单调队列就好

主要是观察转移的规律,抽象这个过程,发现特点,然后优化掉不必要的计算
比如这里就是优化掉了对每一个j的向前遍历寻找最优转移的操作,而是考虑直接动态维护这个决策区间的最大值
也就是所谓的O(1)转移

这也算是单调队列优化dp转移的一个本质了
只是这个复杂一些,开的空间多一些而已
没区别

整个单调队列优化dp的模型就是
f[i]=min(f[j]+val(i,j))(L[i]<=j<=R[i]),然后L,R是单调的,所有的单调队列优化dp都是从这个式子来的,只是一些变形,或者是添加一些复杂的东西
(比如那个平衡树和多重背包的多个单调队列)
但是如果拆开,还是这个式子

单调队列优化里面的val(i,j)拆开后,每一项都只能和i和j中的一个有关,否则维护的东西就只能对现在的状态有用,对于后面的转移则是没有帮助,那也没有优化的必要的了
说这个,其实是因为,其实这种也能维护,但是使用的不再是单纯的单调队列了

 

标签:背包,队列,单调,优化,转移,dp
From: https://www.cnblogs.com/HLZZPawa/p/17847569.html

相关文章

  • 进程间通信的方式之消息队列和共享内存
    消息队列消息队列就是保存在内核中的消息链表,包括Posix消息队列和SystemV消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。共享内存共享内存的机制,......
  • 代码随想录算法训练营第十天 | ● 理论基础 ● 232.用栈实现队列 ● 225. 用队列实现
    今日学习的文章链接和视频链接https://programmercarl.com/栈与队列理论基础.html●232.用栈实现队列varMyQueue=function(){this.stackIn=[];this.stackOut=[]};/***@param{number}x*@return{void}*/MyQueue.prototype.push=funct......
  • P2240 【深基12.例1】部分背包问题(C/C++)
    P2240【深基12.例1】部分背包问题先把物品按照单位重量的价值降序排序,然后依次装入背包。如果背包容量不小于当前要装的物品重量,就全部装入,如果小于,那就剩余多少容量就装多少容量的当前物品。#include<bits/stdc++.h>usingnamespacestd;structjinbi{ doublem; doublev;......
  • 完全背包问题
    题目链接Acwing完全背包问题题目思路完全背包和01背包的区别在于:完全背包中的物品是可以随意数量的。对于一个物品,可以选0个,1个,...,直到选到装不下为止。这里面存在一个转化:只从结果来看,完全背包的代码中,唯一区别就是把f[i-1][j-v[i]]改为f[i][j-v[i]]。代......
  • 01背包问题
    题目链接Acwing01背包问题解题思路处理输入输入n,m,v[i],w[i]等信息算法核心动态规划的思想是通过计算当前的值,这个值能被后来使用,最后得到解属性:求最大价值状态表示:只考虑前i件物品时,体积为j的最大价值思路:只考虑前i件物品时,体积为j的最大价值,这个价......
  • 01背包问题
    1.  二维表示1#include<bits/stdc++.h>2usingnamespacestd;34constintN=1010;5intn,m;//个数和背包容量6intv[N],w[N];//每个物品的体积和价值7intf[N][N];//表示状态89intmain()10{11cin>>n>>m;1213fo......
  • 【HDU 1276】士兵队列训练问题 题解(链表+模拟)
    某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至......
  • 单调栈模型
    单调栈本质:及时去掉无用数据,保证栈中数据有序。 模板题: classSolution:defdailyTemperatures(self,temperatures:List[int])->List[int]:n=len(temperatures)stk=[]ans=[0]*nforiinrange(n-1,-1,-1):......
  • 代码随想训练营第三十七天(Python)| 738.单调递增的数字、968.监控二叉树
    738.单调递增的数字classSolution:defmonotoneIncreasingDigits(self,n:int)->int:#主要思路当前数字比前面数字小时。前面数字-1,当前数字变2为9str_n=str(n)foriinrange(len(str_n)-1,0,-1):ifstr_n[i]<str_n[......
  • 队列
    队列队列(queue)是一种具有「先进入队列的元素一定先出队列」性质的表。由于该性质,队列通常也被称为先进先出(firstinfirstout)表,简称FIFO表。STL队列​ 以下操作的复杂度均为\(O(1)\)。创建队列queue<int>qqueue<char>qqueue<string>q元素访问q.front()返......