首页 > 其他分享 >多重背包III

多重背包III

时间:2022-10-25 20:15:08浏览次数:93  
标签:多重 背包 int 队列 include III

多重背包III(单调队列优化)

原题链接:https://www.acwing.com/problem/content/6/

回忆一下完全背包优化

image

多重背包III思路

彩色铅笔大佬的题解

image

补充:
image

代码
二维
#include<iostream>

using namespace std;

const int N = 1010,M = 20010;

int n,m;
int v[N],w[N],s[N];
int f[N][M];
int q[M]; // 数组模拟队列

int main()
{
    cin >> n >> m ; 
    for(int i = 1;i <= n;i ++) cin >> v[i] >> w[i] >> s[i];
    
    for(int i = 1;i <= n;i ++)
    {
        for(int r = 0; r < v[i]; r ++)
        {
            int head = 0,tail = -1;
            for(int j = r; j <= m;j += v[i])
            {
                // 判断队头是否滑出
                if(head <= tail && q[head] < j-s[i]*v[i]) head ++;
                // 保证模拟队列递减(队头为最大值)
                while(head <= tail && f[i-1][q[tail]]+(j-q[tail])/v[i]*w[i] <= f[i-1][j]) tail --;
                q[++ tail] = j;
                f[i][j] = max(f[i][j],f[i-1][q[head]] + (j-q[head])/v[i]*w[i]);
            }
        }
    }
    cout << f[n][m];
    return 0;
}
一维
#include<iostream>
#include<cstring>

using namespace std;

const int N = 1010,M = 20010;

int n,m;
int v[N],w[N],s[N];
int f[M],g[M];
int q[M]; // 数组模拟队列

int main()
{
    cin >> n >> m ; 
    for(int i = 1;i <= n;i ++) cin >> v[i] >> w[i] >> s[i];
    
    for(int i = 1;i <= n;i ++)
    {
        memcpy(g,f,sizeof g);
        for(int r = 0; r < v[i]; r ++)
        {
            int head = 0,tail = -1;
            for(int j = r; j <= m;j += v[i])
            {
                // 判断队头是否滑出
                if(head <= tail && q[head] < j-s[i]*v[i]) head ++;
                // 保证模拟队列递减(队头为最大值)
                while(head <= tail && g[q[tail]]+(j-q[tail])/v[i]*w[i] <= g[j]) tail --;
                q[++ tail] = j;
                f[j] = max(f[j],g[q[head]] + (j-q[head])/v[i]*w[i]);
            }
        }
    }
    cout << f[m];
    return 0;
}

标签:多重,背包,int,队列,include,III
From: https://www.cnblogs.com/rdisheng/p/16826129.html

相关文章

  • 【算法学习】完全背包问题公式记录
    朴素f[i][j]=max(f[i-1][j],f[i-1][j-v]+w,f[i-1][j-2v]+2w,...)f[i][j-v]=max(f[i-1][j-v],f[i-1][j-2v]+w,...)=>f[i][j]=max......
  • 背包问题的倒序枚举与正序枚举
    这可能是困扰很多人很长时间的问题吧。先把各个变量列出来体积为的背包,有个物品,每个物品的体积为,价值为,每个物品装一次,求最大价值来这看的肯定都是学习过基础背包的人,如果没......
  • 背包问题常见解题策略与例题解析
    背包问题作为常见的一种Dp题目的变法多种多样然而只要你理解透了背包的做法和各种优化模型就显而易见了千万不要似懂非懂如果还有疑虑可以参考我的另一篇文章​​​背......
  • POJ 2184(01背包+滚动数组)
    01背包模板题Programdd;constmaxn=1000;maxv=100000;minv=-100000;NULL=-2139062144;varn,i,j,ans,p,np:longint;ts,tf:array[1..maxn]oflongint;......
  • BYSBZ 2748(音量调节-01背包)
    第一题:音量调节(changingsounds)时间限制:1秒空间限制:64MB输入:changingsounds.in输出:changingsounds.out问题描述一个吉他手准备参加一场演出。他不喜欢在演出时始终使......
  • 连续背包 (背包套背包)
    连续背包(bag)【问题描述】从T组物品中选出一些物品,放入背包中,求剩余空间的最小值。限制条件:从每组物品中挑选物品必须要选取连续的一段。就是说,如果这组物品共有n个:物品1、......
  • 7-1 0-1背包
    7-10-1背包分数25 作者郑琪单位广东外语外贸大学给定n(n<=100)种物品和一个背包。物品i的重量是wi,价值为vi,背包的容量为C(C<=1000)。问:应如何......
  • 多重循环~2出现的次数
    题目描述:输入输入共1行,为两个正整数L和R,之间用一个空格隔开。输出输出共1行,表示数字2出现的次数1#include<stdio.h>2intmain(){3intm,n;4......
  • CF 788C(The Great Mixing-背包)
    有k瓶饮料,碳酸含量为a_1/1000,每瓶饮料取整数分,问怎么凑出x/1000的饮料。0<=a_i<=1000显然a1−n+a2−n+...+ak−n=0建图,在[-1000,1000]上每个点连出k条边,求经过0点的最小......
  • 多重循环~平面分割
    题目描述:输入第一行输入一个整数m(m<=100),表示有m组测试数据。接下来的m行,每行有两个整数n和p,分别表示平面内的直线数和相交于一点直线数。 输出每组测试数据输出......