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