AcWing算法提高课 多重背包问题的单调队列优化
多重背包问题可以用单调队列进行优化
原理见:提高课1.3.1 背包模型(一)
离题:6. 多重背包问题 III
单调队列的deque实现如下:

#include<bits/stdc++.h> using namespace std; int v[1010]; int w[1010]; int s[1010]; int dp[1010][20010]; int main() { int N,V; cin>>N>>V; for(int i=1;i<=N;i++) { cin>>v[i]>>w[i]>>s[i]; } for(int i=1;i<=N;i++) { for(int j=0;j<v[i];j++) { deque<int> que; for(int k=j;k<=V;k+=v[i]) { while(que.size()) { if(dp[i-1][k]>=dp[i-1][que.back()]+(k-que.back())/v[i]*w[i]) que.pop_back(); else break; } que.push_back(k); if(k-que.front()>s[i]*v[i]) que.pop_front(); if(que.size()!=0) dp[i][k]=dp[i-1][que.front()]+(k-que.front())/v[i]*w[i]; else dp[i][k]=dp[i-1][k]; } } } int res=0; for(int i=0;i<=V;i++) res=max(res,dp[N][i]); cout<<dp[N][V]<<endl; }
注意,由于deque速度比较慢,在数据量较大的情况下,可能会超时。
故单调队列推荐使用数组进行模拟。
数组模拟就是使用hh和tt记录队列的头部和队列的尾部的下一个位置,非常直观。
推荐写完deque的解法后,在直接修改即可。

#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; int v[1010]; int w[1010]; int s[1010]; int dp[1010][20010]; int que[20010]; int main() { int N,V; cin>>N>>V; for(int i=1;i<=N;i++) { cin>>v[i]>>w[i]>>s[i]; } for(int i=1;i<=N;i++) { for(int j=0;j<v[i];j++) { int hh=0,tt=0; for(int k=j;k<=V;k+=v[i]) { while(hh<tt) { if(dp[i-1][k]>=dp[i-1][que[tt-1]]+(k-que[tt-1])/v[i]*w[i]) tt--; else break; } que[tt]=k; tt++; if(k-que[hh]>s[i]*v[i]) hh++; if(hh<tt) dp[i][k]=dp[i-1][que[hh]]+(k-que[hh])/v[i]*w[i]; else dp[i][k]=dp[i-1][k]; } } } int res=0; for(int i=0;i<=V;i++) res=max(res,dp[N][i]); cout<<dp[N][V]<<endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!