首页 > 其他分享 >多重背包 (单调队列)

多重背包 (单调队列)

时间:2023-08-06 17:12:07浏览次数:46  
标签:std 背包 队列 cin long int while -- 单调

题目链接


#include <bits/stdc++.h>
using ll = long long;
const int N = 1E3 + 5 , M = 2E4 + 5;

int n,m;
int v[N],w[N],s[N];
int f[M];
int l,r,q[M];

int calc(int i,int u,int k) {
	return f[k * v[i] + u] - k * w[i];
}

int main() 
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	
	std::cin >> n >> m;
	for (int i = 1 ; i <= n ; ++i) {
		std::cin >> v[i] >> w[i] >> s[i];
	}
	
	for (int i = 1 ; i <= n ; ++i) 
	{
		for (int u = 0 ; u < v[i] ; ++u)
		{
			//j = p * v[i] + u;
			//_j = k * v[i] + u;
			// f[j] = max{f[_j] + (p - k) * w[i]}; 
			//处理出 f[k * v[i] + u] - k * w[i] 与 k 相关 
			//预处理队列内容 
			int maxp = (m - u) / v[i];
			l = 1 , r = 0;//队列要求下标递减 
			for (int k = maxp - 1 ; k >= std::max(maxp - s[i] , 0) ; --k) {
//				while (l <= r && q[l] > maxp - 1) ++l; 在这里没有必要 
				while (l <= r && calc(i , u , q[r]) <= calc(i , u , k)) --r;
				q[++r] = k;
			} 
			
			for (int p = maxp ; p >= 0 ; --p) 
			{
				while (l <= r && q[l] > p - 1) ++l;
				
				if (l <= r)
					f[p * v[i] + u] = std::max(f[p * v[i] + u] , calc(i , u , q[l]) + p * w[i]);
					
				//为下一个集合的扩展一位 
				if (p - s[i] - 1 >= 0) {
					while (l <= r && calc(i , u , q[r]) <= calc(i , u , p - s[i] - 1)) r--;
					q[++r] = p - s[i] - 1;
				}
			}
			
		}
	}
	
	int ans = 0;
	for (int i = 0 ; i <= m ; ++i)
		ans = std::max(ans , f[i]);
	std::cout << ans << '\n';
	
	return 0;	
} 

标签:std,背包,队列,cin,long,int,while,--,单调
From: https://www.cnblogs.com/xqy2003/p/17609583.html

相关文章

  • dijkstra + 单调栈优化
    打Div.3发现两个最短路板子题一个用的SPFA一个用的邻接矩阵,赶紧补个。#include<iostream>#include<queue>#defineMAXN20010usingnamespacestd;constintinf=2147483647;intn,m,s,t,cnt;intdis[MAXN],h[MAXN],to[MAXN],val[MAXN],nxt[MAXN];boolvis[MAXN]......
  • 王道408用数组,链表以及双向链表实现栈、队列
    我在电脑上敲了一遍,又在纸上模拟了一遍下面记录在电脑上敲的:一、用数组实现栈#include<stdio.h>#include<string.h>#defineMaxSize50typedefstruct{intdata[MaxSize];inttop;}stack;voidInitStack(stack&S){S.top=-1;S.data[0]=5;......
  • [代码随想录]Day10-栈与队列part02
    题目:20.有效的括号思路:很简单的一个栈的题目:如果是左括号就存如果是右括号就和栈顶的匹配匹配失败就返回false匹配成功就删除栈顶元素如果结束后是空就说明匹配完成这里需要注意的一个点是可以用map来代替过多的ifelse,希望能学会!代码:varpairs=map[byte]byte{......
  • 总结: [01背包] 空间优化后内层循环为啥是逆序的?
    总结:[01背包] 空间优化后内层循环为啥是逆序的?首先,这是一个困扰了不少人的问题,虽然网上有挺多的解释,但是有的想起来比较费劲,于是乎,就有了这篇题解题目分析首先,01背包问题是一个非常非常非常经典的动态规划问题(后文简称“动规”或“dp”)。 因为百度百科上的题目分析......
  • 【数据结构 | 入门】堆栈与队列(问题引入&实现&算法优化)
    ......
  • 代码随想录算法训练营第十天| 232.用栈实现队列 225. 用队列实现栈
    232.用栈实现队列   卡哥建议:大家可以先看视频,了解一下模拟的过程,然后写代码会轻松很多。  题目链接/文章讲解/视频讲解:https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.html   做题思路:   记住栈和队列的......
  • [代码随想录]Day09-栈与队列part01
    题目:232.用栈实现队列思路:因为go没有栈和队列的类型,直接自己写就行了。比较简单的实现,具体看代码中的注释。代码:typeMyQueuestruct{numbers[]int}funcConstructor()MyQueue{returnMyQueue{numbers:[]int{}}}func(this*MyQueue)Push(xint){......
  • 优先队列
    元素入队时间复杂度O(logn),查询O(1),总体排序时间复杂度O(logn),用于优化一些大数据范围的排序,具体用法如下:#include<bits/stdc++.h>usingnamespacestd;priority_queue<int,vector<int>,less<int>>q;//less<int>:和greater<int>相反structnode{inti,v;};pr......
  • Newnode's NOI(P?)模拟赛 第二题 dp决策单调优化
    其实直接暴力O(n3)DP+O2O(n^3)DP+O_2O(n3)DP+O2优化能过…CODEO(n3)O(n^3)O(n3)先来个O(n3)O(n^3)O(n3)暴力DP(开了O2O_2O2)100分代码(极限数据0.5s0.5s0.5s)#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;......
  • [算法学习笔记] 多重背包--二进制拆分
    多重背包回顾一下多重背包是什么?有\(n\)种物品,每个物品都有有限个,每个物品都有重量和价值两个参数,你有一个限重为\(W\)的背包,求背包内价值最大。我们朴素的做法是将多重背包拆分成01背包求解,因为每个物品都有有限个,假设第\(i\)个物品有\(j\)个,那么跑\(j\)次01背包即可。但是这......