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

    题目描述

    \(N\) 种物品和一个容量是 \(V\) 的背包。

    \(i\) 种物品最多有 \(s_i\) 件,每件体积是 \(v_i\),价值是 \(w_i\)

    求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
    输出最大价值。

    范围

    \(0<N≤1000\)
    \(0<V≤20000\)
    \(0<v_i,w_i,s_i≤20000\)

    题解

    考虑\(f_{j * k \times v}\)是由若干个{\(f_j,f_{j+v},f_{j+2v}…\)}最大值转移而来。

    写出dp方程之后用单调队列转移即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 20010;
    int n,m;
    int pre[N];
    int dp[N];
    int q[N];
    
    int main () {
    	cin >> n >> m;
    	for(int i = 1;i <= n; ++i) {
    		int s,v,w;
    		cin >> v >> w >> s;
    		memcpy(pre,dp,sizeof dp);
    		for(int j = 0;j < v; ++j) {
    			int head = 1;
    			int tail = 0;
    			for(int k = j;k <= m; k += v) {
    				while(head <= tail and q[head] < k - s * v) head ++;
    				while(head <= tail and pre[q[tail]] - (q[tail] - j) / v * w <= pre[k] - (k - j) / v * w)
    					tail --;
    				q[++tail] = k;
    				if(head <= tail) dp[k] = pre[q[head]] - (q[head] - k) / v * w;
    			}
    		}
    	}
    	cout << dp[m] << endl;
    	return 0;
    }
    
    
  • 相关阅读:
    mac下mysql忘记了密码怎么办
    图片标签的四种路径
    三栏布局
    MongoDB学习笔记
    mysql B+ 树
    移动终端设备ID
    前端基础HTML以及常用的标签
    python--os模块
    python--基本数据 类型
    python基础3、4---流程控制、运算符
  • 原文地址:https://www.cnblogs.com/akoasm/p/15153838.html
Copyright © 2011-2022 走看看