E13 背包DP 多重背包 单调队列优化

视频链接:E13 背包DP 多重背包 单调队列优化——信息学奥赛算法_哔哩哔哩_bilibili

 

E11【模板】单调队列 滑动窗口最值 - 董晓 - 博客园

Luogu P1776 宝物筛选

复制代码
// 单调队列 O(n*W)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=40005;
int n,W,w,v,m,q[N];
int f[N],g[N];

int main(){
  scanf("%d%d",&n,&W);        //种类n,容量W
  while(n--){
    memcpy(g,f,sizeof(f));    //f备份
    scanf("%d%d%d",&v,&w,&m); //价值,重量,数量
    for(int j=0;j<w;j++){     //0,1,2...w-1个类
      int h=1,t=0;
      for(int k=j;k<=W;k+=w){ //0,w,2w,3w...
        if(h<=t && q[h]<k-m*w) h++; //[k-m*w...k-w],k
        while(h<=t && g[k]>=g[q[t]]+(k-q[t])/w*v) t--; //q[t]...k
        q[++t]=k;
        f[k]=g[q[h]]+(k-q[h])/w*v; //q[h]...k
      }
    }
  }
  printf("%d\n",f[W]);
}
复制代码

 

复制代码
// 单调队列 O(n*W)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=40005;
int n,W,w,v,m,q[N];
int f[N],g[N];

int main(){
  scanf("%d%d",&n,&W);        //种类n,容量W
  while(n--){
    memcpy(g,f,sizeof(f));    //f备份
    scanf("%d%d%d",&v,&w,&m); //价值,重量,数量
    for(int j=0;j<w;j++){     //0,1,2...w-1个类
      int h=1,t=0;
      for(int k=j;k<=W;k+=w){ //0,w,2w,3w...
        while(h<=t && g[k]>=g[q[t]]+(k-q[t])/w*v) t--; //q[t]...k
        q[++t]=k;      
        if(h<=t && q[h]<k-m*w) h++; //[k-m*w...k-w],k
        f[k]=g[q[h]]+(k-q[h])/w*v; //q[h]...k
      }
    }
  }
  printf("%d\n",f[W]);
}
复制代码

 

posted @   董晓  阅读(805)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示