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

    代码

    /*
    思路来源:
    f(i, j) = max(f(i - 1, j), f(i - 1, j - v) + w, f(i - 1, j - 2 * v) + 2 * w, ..., f(i - 1, j - s * v) + s * w)
    f(i, j - v) = max(         f(i - 1, j - v)    , f(i - 1, j - 2 * v) + w,          f(i - 1, j - s * v) + (s - 1) * w + f(i - 1, j - (s + 1) * v) + s * w)
    ......
    f(i, j - s * v) = max(f(i - 1, j - s * v), ...)
    这不就是窗口大小为 s 的滑动窗口吗
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int N = 20010;
    
    int n, m;
    int f[N], g[N], q[N];
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i ++) {
            int v, w, s;
            scanf("%d%d%d", &v, &w, &s);
            memcpy(g, f, sizeof f);
            for(int j = 0; j < v; j ++) { // 序列的起点
                // f(0), f(0 + v), f(0 + 2 * v) + ...
                // f(1), f(1 + v), f(1 + 2 * v) + ...
                // f(j), f(j + v), f(j + 2 * v) + ...
                // 0 <= j < v
                int hh = 0, tt = -1;
                for(int k = j; k <= m; k += v) { // 枚举序列
                    // 序列下标是 j, j + v, j + 2 * v, ...
                    // 序列值为 f(j), f(j + v) - w, f(j + 2 * v) - 2 * w
                    // 当前枚举的下标是 k
                    if(hh <= tt && q[hh] < k - s * v) hh ++; 
                    // 上一步的含义是,因为窗口是从 k 往前 s 个元素,因此要判断是否在窗内
                    if(hh <= tt) f[k] = max(f[k], g[q[hh]] + (k - q[hh]) / v * w);
                    // 举个例子,f(i, j + s * v) = 
                    // = max(f(i - 1, j) + s * w, f(i - 1, j + v) + (s - 1) * w, ..., f(i - 1, j + s * v))
                    // = max(f(i - 1, j), f(i - 1, j + v) - w, ..., f(i - 1, j + s * v) - s * w) + s * w
                    while(hh <= tt && g[q[tt]] - (q[tt] - j) / v * w <= g[k] - (k - j) / v * w) tt --;
                    // 队列是单调递减的
                    q[++ tt] = k;
                }
            }
        }
        printf("%d
    ", f[m]);
        return 0;
    }
    
  • 相关阅读:
    Linux 动态库剖析
    【jquery mobile笔记二】jquery mobile调用豆瓣api示例
    地标性建筑
    地标性建筑
    翻译的艺术 —— 专有名词(广告词、国外品牌、语言等)
    翻译的艺术 —— 专有名词(广告词、国外品牌、语言等)
    黄金白银、古董与收藏
    黄金白银、古董与收藏
    经典书单 —— 计算机图形学
    经典书单 —— 计算机图形学
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/14460159.html
Copyright © 2011-2022 走看看