码迷,mamicode.com
首页 > 其他好文 > 详细

单调队列优化多重背包

时间:2019-03-14 18:36:05      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:freopen   oid   amp   std   style   code   c++   i++   print   

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

直接上模板好了。

技术图片
 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\n", 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代码

 

单调队列优化多重背包

标签:freopen   oid   amp   std   style   code   c++   i++   print   

原文地址:https://www.cnblogs.com/huyufeifei/p/10531883.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!