单调队列优化多重背包

Posted featherzhy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调队列优化多重背包相关的知识,希望对你有一定的参考价值。

思路

这里只是贴一下 JZOJ4224.食物 的代码,挺有意思的水题,虽然一眼就看得出来两个多重背包,但是比较有意思的一个地方是在处理交通工具时为了求出答案,把价格当做体积,把最大装载量当做价值。一切思路还是为了答案服务,这是值得记住的。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 2100;
const int MAX = 2000000 + 10;
int t, n, m, p, l, r, num[N], v[N], w[N], maxx[N], price[N], sum[N], V, f[MAX], f1[MAX];
struct node

    int po, val;
q[MAX];
void bag()

    for (int i = 1; i <= m; i++)
    
        sum[i] = min(sum[i], 50000 / price[i]);
        for (int b = 0; b < price[i]; b++)
        
            l = r = 1;
            int a = (50000 - b) / price[i];
            for (int k = 0; k <= a; k++)
            
                int y = f[k * price[i] + b] - k * maxx[i];
                while (l < r && q[r - 1].val <= y) r--;
                q[r].po = k;
                q[r++].val = y;
                while (l < r && q[l].po < k - sum[i]) l++;
                f[k * price[i] + b] = max(q[l].val + k * maxx[i], f[k * price[i] + b]);
            
        
    

void bag1()

    V = p + 100;
    for (int i = 1; i <= n; i++)
    
        num[i] = min(num[i], V / v[i]);
        for (int b = 0; b < v[i]; b++)
        
            l = r = 1;
            int a = (V - b) / v[i];
            for (int k = 0; k <= a; k++)
            
                int y = f1[k * v[i] + b] - k * w[i];
                while (l < r && q[r - 1].val <= y) r--;
                q[r].po = k;
                q[r++].val = y;
                while (l < r && q[l].po < k - num[i]) l++;
                f1[k * v[i] + b] = max(f1[k * v[i] + b], q[l].val + k * w[i]);
            
        
    
    for (int i = 1; i <= 50000; i++)
        if (f1[f[i]] >= p)
        
            printf("%d\\n", i);
            return;
        
    printf("TAT\\n");
    return;

int main()

    scanf("%d", &t);
    for (int o = 1; o <= t; o++)
    
        memset(f, 0, sizeof f);
        memset(f1, 0, sizeof f1);
        scanf("%d%d%d", &n, &m, &p);
        for (int i = 1; i <= n; i++)
            scanf("%d%d%d", &w[i], &v[i], &num[i]);
        for (int i = 1; i <= m; i++)
            scanf("%d%d%d", &maxx[i], &price[i], &sum[i]);
        bag();
        bag1();
    
    return 0;

以上是关于单调队列优化多重背包的主要内容,如果未能解决你的问题,请参考以下文章

单调队列优化多重背包

单调队列优化多重背包

单调队列优化多重背包

poj1742 Coins(多重背包+单调队列优化)

单调队列优化多重背包

单调队列优化多重背包