单调队列优化多重背包

Posted huyufeifei

tags:

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

就是按照 % 体积的余数来分组,每组单调队列优化。

直接上模板好了。

技术图片
 1 #include <bits/stdc++.h>
 2 
 3 typedef long long LL;
 4 const int N = 100010;
 5 
 6 int n, V, cnt[N], cost[N];
 7 LL f[2][N], val[N], p[N], top, head;
 8 
 9 inline void Max(LL &a, const LL &b) {
10     a < b ? a = b : 0;
11     return;
12 }
13 
14 int main() {
15 
16     freopen("bag.in", "r", stdin);
17     freopen("bag.out", "w", stdout);
18 
19     scanf("%d%d", &n, &V);
20     for(int i = 1; i <= n; i++) {
21         scanf("%d%d%lld", &cnt[i], &cost[i], &val[i]);
22     }
23     LL ans = 0;
24     for(int i = 1; i <= n; i++) {
25         for(int j = 0; j < cost[i]; j++) {
26             p[head = top = 1] = 0;
27             for(int g = 1; g * cost[i] + j <= V; g++) {
28                 while(g - p[head] > cnt[i]) head++;
29                 int t = p[head];
30                 Max(f[i & 1][g * cost[i] + j], f[(i - 1) & 1][t * cost[i] + j] + (g - t) * val[i]);
31                 while(top >= head && f[(i - 1) & 1][cost[i] * p[top] + j] + (g - p[top]) * val[i] <= f[(i - 1) & 1][g * cost[i] + j]) {
32                     top--;
33                 }
34                 p[++top] = g;
35             }
36         }
37         for(int j = 0; j <= V; j++) {
38             Max(ans, f[i & 1][j]);
39             f[(i - 1) & 1][j] = f[i & 1][j];
40         }
41     }
42     
43     printf("%lld
", ans);
44     return 0;
45 }
46 /*
47 5 50
48 1 1 7
49 2 1 4
50 2 4 1
51 3 1 3
52 2 3 8
53 -------------- 42
54 */
AC代码

 

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

单调队列优化多重背包

单调队列优化多重背包

单调队列优化多重背包

单调队列优化多重背包

单调队列优化多重背包

背包问题入门(单调队列优化多重背包