zoukankan      html  css  js  c++  java
  • 多重背包单调队列优化

    for (int i = 1; i <= n; ++i) {
        Ni = Num[i]; Vi = V[i]; Wi = W[i];
        for (int j = 0; j < Vi; ++j) {
            Head1 = Tail1 = 0;
            Head2 = Tail2 = 0;
            Cnt = 0;
            for (int k = j; k <= m; k += Vi) {
                if (Tail1 - Head1 == Ni + 1) {
                    if (Q2[Head2 + 1] == Q1[Head1 + 1]) ++Head2;
                    ++Head1;
                }
                t = f[k] - Cnt * Wi;
                Q1[++Tail1] = t;
                while (Head2 < Tail2 && Q2[Tail2] < t) --Tail2;
                Q2[++Tail2] = t;
                f[k] = Q2[Head2 + 1] + Cnt * Wi; 
                ++Cnt;
            }
        }
    }
    View Code

    考虑多重背包与01背包,完全背包的区别。

    多重背包每种物品只能选最多m个。

    那么我们的任务就是,如何控制多重背包最多选m个物品。

    自然想到滑动窗口。当窗口宽度大于v[i]*m的时候把前面的元素删除

    但是如果单纯的滑动,对与某一个f[k],f[k-v[i]]可能已经被这个物品更新过了

    设V=a*vi+b;

    设k=c*vi+d;

    枚举c,d就可以均匀的枚举到所有小于V的值,且不重复,复杂度O(V)

    于是枚举每一个d值,对于每个d再枚举c,当c>m时将队首删除

    每一个枚举到的值用单调队列维护。每次f[k]就是队列最大值

  • 相关阅读:
    如何搭建SVN的客户端和使用
    SVN服务器的本地搭建和使用
    grep命令
    cat命令
    cut命令
    yum 命令
    XPath、XQuery 以及 XSLT 函数
    XPath 实例
    XPath 运算符
    XPath Axes(轴)
  • 原文地址:https://www.cnblogs.com/Amphetamine/p/7492791.html
Copyright © 2011-2022 走看看