首页 > 其他 > 详细

混合背包(单调队列优化多重背包)(模板)

时间:2019-09-18 22:11:11      阅读:101      评论:0      收藏:0      [点我收藏+]

简述

如标题所述,放一下混合背包最优时间的模板

技术分享图片

 代码区

技术分享图片
#include<bits/stdc++.h>
using namespace std;
const int Max = 1e5+10;

int n, v;
int val[Max], vol[Max], num[Max];
int que[Max];
int dp[Max];

void work()
{
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= n; i++)
    {
        if (num[i] == 1)                    //01背包
        {
            for (int j = v; j >= vol[i]; j--)
                dp[j] = max(dp[j], dp[j - vol[i]] + val[i]);
            continue;
        }
        if (vol[i] * num[i] >= v)            //完全背包,这个比较关键,因为用单调队列处理非常耗时
        {
            for (int j = vol[i]; j <= v; j++)
                dp[j] = max(dp[j], dp[j - vol[i]] + val[i]);
            continue;
        }
        for (int res = 0; res < vol[i]; res++)                            //枚举余数
        {
            int head = 0, tail = -1;
            for (int k = 0; k <= (v - res) / vol[i]; k++)                //枚举k‘,即等差数列的项数,每次更新同余数的数
                //因为只有余数相同的数才会互相影响
            {
                int value = dp[k * vol[i] + res] - k * val[i];            //当前的价值

                if (tail - head == k)                                    //就算用尽所有材料也无法从que[head]转移
                    head++;
                while (head <= tail && que[tail] <= value)                //取最大值
                    tail--;
                tail++;
                que[tail] = value;
                dp[k * vol[i] + res] = que[head] + k * val[i];
            }
        }
    }
}
View Code

混合背包(单调队列优化多重背包)(模板)

原文:https://www.cnblogs.com/winter-bamboo/p/11545483.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!