动态规划之完全背包问题

2023-11-15

完全背包问题

题目

N N N 种物品和一个容量为 V V V 的背包,每种物品都有无限件可用。放入第 i i i 种物品的费用是 C i C_i Ci,价值是 W i W_i Wi。求解:将哪些物品装入背包,可使这些物品耗费的费用总和不超过背包容量,且价值总和最大。

基本思路

与01背包问题相似,唯一不同是每种物品有无限件。即从物品角度,相关策略从取或不取两种,变为取 0 件、取 1 件、取 2 件…直到取 ⌊ V / C i ⌋ \lfloor V/C_i \rfloor V/Ci 件。

按01背包思路,令 F [ i , v ] F[i, v] F[i,v] 表示前 i i i 种物品正好放入一个容量为 v v v 的背包的最大价值。状态转移方程为:
F [ i , v ] = m a x { F [ i − 1 , v − k C i ] + k W i ∣ 0 ≤ k C i ≤ v } F[i, v] = max\{F[i-1,v-kC_i]+kW_i|0 \leq kC_i \leq v\} F[i,v]=max{F[i1,vkCi]+kWi0kCiv}
和01一样共有 O ( V N ) O(VN) O(VN) 个状态需求解,但解每个状态的时间不是常数了,解状态 F [ i , v ] F[i, v] F[i,v] 的时间是 O ( v / C i ) O(v/C_i) O(v/Ci) ,总复杂度为 O ( N V ∑ V / C i ) O(NV\sum V/C_i) O(NVV/Ci)

优化

  1. O ( N 2 ) O(N^2) O(N2) 优化
    若物品 i i i j j j 满足 C i ≤ C j C_i \leq C_j CiCj W i ≥ W j W_i \geq W_j WiWj 可将物品j直接去除。

  2. O ( V + N ) O(V + N) O(V+N)优化
    先将费用大于 V V V 的物品去除,然后类似计数排序,计算出费用相同的物品中价值最高的物品。

转化为01背包问题求解

简单做法

可用把第 i i i 种物品转化为 ⌊ V / C i ⌋ \lfloor V/C_i \rfloor V/Ci 件费用及价值都不变的物品,然后求解01背包。

更高效转化

把第 i i i 种物品拆成费用为 C i 2 k C_i2^k Ci2k 、价值为 W i 2 k W_i2^k Wi2k 的若干件物品,其中 k k k 是满足 C i 2 k ≤ V C_i2^k \leq V Ci2kV 的非负整数,复杂度 O ( log ⁡ ⌊ V / C i ⌋ ) O(\log \lfloor V/C_i \rfloor) O(logV/Ci)

模板

typedef long long ll;

void CompletePack(ll F[], ll C, ll W, ll Cap)
{
    for(int v = C; v <= Cap; v++)
        F[v] = max(F[v], F[v - C] + W);
}

ll Solve(const ll C[],const ll W[], const ll N, const ll Cap)
{
    ll F[Cap+1];
    memset(F,0,sizeof(F));

    //优化
    bool Use[N+1];
    
    // O(N^2)优化
    // memset(Use,true,sizeof(Use));
    // for(int i = 1; i <= N; i++)
    //     for(int k = i+1; k <= N; k++)
    //         if(C[i] <= C[k] && W[i] >= W[k])
    //             Use[k] = false;
    
    // O(V + N)优化
    memset(Use, false, sizeof(Use));
    map<ll, int> Cnt;
    for(int i = 1; i <= N; i++)
    {      
        if(C[i] > Cap)
            continue;
        if(Cnt[C[i]] == 0)
            Cnt[C[i]] = i, Use[i] = true;
        else if(W[i] > W[Cnt[C[i]]])
            Use[Cnt[C[i]]] = false, Use[i] = true, Cnt[C[i]] = i;
    }

    for(int i=1; i <= N; i++)
        if(Use[i]) //优化
            CompletePack(F, C[i], W[i], Cap);
    
    return F[Cap];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态规划之完全背包问题 的相关文章

  • python selenium爬虫自动登录实例

    一 概述 我们要先安装selenium这个库 使用pip install selenium 命令安装 selenium这个库相当于机器模仿人的行为去点击浏览器上的元素 这时我们要用到一个浏览器的驱动 这里我用的是谷歌浏览器 二 安装驱动 确
  • Golang RabbitMQ实现的延时队列

    文章目录 前言 一 延时队列与应用场景 二 RabbitMQ如何实现延时队列 实现延时队列的基本要素 整体的实现原理如下 三 Go语言实战 生产者 消费者 前言 之前做秒杀商城项目的时候使用到了延时队列来解决订单超时问题 本博客就总结一下G

随机推荐

  • C/C++ 内存管理(malloc/calloc/realloc、free 和 new 、 delete区别;内存泄漏)

    C C 内存分布 int globalVar 1 static int staticGlobalVar 1 globalVar和staticGlobalVar是在main函数之前初始化 在哪都能用 作用域是全局的 区别 它俩的链接属性不一样
  • 全景分割(Panoptic Segmentation)(CVPR 2019)

    全景分割 Panoptic Segmentation CVPR 2019 摘要 1 导言 2 相关工作 3 全景分割格式 4 全景分割度量 4 1 片段匹配 4 2 PQ计算 4 3 与现有度量的比较 5 全景分割数据集 6 人类一致性研究
  • PAL 和NTSC说明?

    PAL 720 576 25HZ NTSC 720 480 30HZ 576i是一种视频格式的缩写 字母 i 表示 隔行扫描 数字576表示水平方向有576条 扫描线 通常通常垂直分辨率为720或者704像素 换句话说 标准画质电视 SDT
  • STM32学习笔记:CAN总线的过滤器

    STM32 CAN控制器 提供了28个可配置的筛选器组 F1仅互联型才有28个 其他的只有14个 STM32 CAN控制器每个筛选器组由2个32位寄存器组成 CAN FxR1和CAN FxR2 x 0 27 根据位宽不同 每个筛选器组可提供
  • 使用cBioPortal查看TCGA肿瘤数据

    欢迎关注 生信修炼手册 cBioPortal整合了来自TCGA CCLE以及几个独立的大型肿瘤研究项目的数据 构建了一个易于使用的网站 不需要有深厚的计算机功底 也可以通过该网站查询 分析 可视化肿瘤的相关结果 针对该网站的使用 官方专门发
  • leetcode 322. Coin Change硬币交换问题

    题目详细 描述 You are given coins of different denominations and a total amount of money amount Write a function to compute th
  • 美国国家安全局(NSA)网络攻击主战武器NOPEN

    国家计算机病毒应急处理中心14日正式发布了美国国家安全局专用 NOPEN 远控木马分析报告 揭露了美国情治部门的网络间谍手段 国家计算机病毒应急处理中心 信息安全摘要 近日 国家计算机病毒应急处理中心对名为 NOPEN 的木马工具进行了攻击
  • 排序算法--冒泡排序

    冒泡排序 基本思想 实例演示 代码实现 基础实现 代码优化 基本思想 基本思想 冒泡排序 类似于水中冒泡 较大的数沉下去 较小的数慢慢冒起来 假设从小到大 即为较大的数慢慢往后排 较小的数慢慢往前排 直观表达 每一趟遍历 将一个最大的数移到
  • 雅可比(jacobi)迭代法 matlab实现

    clc clear n input 请输入矩阵阶数 n for i 1 n fprintf 请输入矩阵第 d行 n i A i input end A B 1 input 请输入B向量 n B for i 1 n x i 0 x2 i 0
  • 动态规划之完全背包问题

    完全背包问题 题目 有 N N N 种物品和一个容量为 V V V 的背包 每种物品都有无限件可用 放入第 i
  • javascript 的MD5代码备份,跟java互通

    var MD5 function string function RotateLeft lValue iShiftBits return lValue lt
  • mybatis 批量增加 Parameter '__frch_item_0' not found. Available parameters are [list]

    当在mybatis用到foreach的时候 会报这个错误Parameter frch item 0 not found Available parameters are list 会出现的几种解决方案 例子 sql view plain c
  • 【Linux操作系统】【综合实验二 vi应用与shell脚本编辑】【浅试编辑命令】

    文章目录 一 实验目的 二 实验要求 三 实验内容 1 继续练习Linux系统的文件类 目录类 进程管理类与磁盘操作类常用命令 并使用常见的选择项 2 了解ed ex行编辑器与Emacs全屏幕编辑器的工作模式 基本操作命令 3 掌握vi的编
  • 静态测试

    之前对 静态测试 一直不怎么理解 一直徘徊在为什么要进行静态测试 看了下面这几篇文章 突然觉得的柳暗花明了 目前我正在测试的项目xx让我烦心的问题终于找到出路了 http qa taobao com p 8017 http qa taoba
  • 资产收集的方法总结

    资产收集的方法总结 文章目录 资产收集的方法总结 前言 一 资产收集基本名词概念 二 相关收集方法 1 fofa 2 google搜索语法 3 logo 4 favicon ico 5 关键字 6 维基百科 7 天眼查 企查查 8 微信公众
  • 设计模式之UML类图该怎么画

    关于可维护 可复用 可扩展 灵活性好的理解 生活中 印刷术和活字印刷 当需要对某些内容修改时 印刷术只要有一丁点变化 就需要重头再来 而活字印刷只需要进行部分修改即可 可维护 只更改要更改的内容 可复用 之前的内容并非用完就无用 后面仍可使
  • Caused by: java.lang.NoClassDefFoundError: javax/tools/ToolProvider

    解决方案 在pom文件中的scala maven plugin插件下面加入一个参数 pom xml配置如下
  • python + selenium实现自动登录操作(以淘宝为例)

    selenium操作不熟练的可以查看一下这篇文章 selenium操作大全 一 登录前准备操作 定位一下相对应html位置 输入一般为input标签 登录按钮一般为button 输入账号密码那块 定位代码 driver find eleme
  • 电脑主板跳线_电脑基础进阶必学知识,详解电脑主板跳线!

    在DIY装机时新手总会有不同的问题 虽然目前网上流传着各种版本的教学文章或者视频 但是细致的小技巧讲解还是有限 不少网友在装机的时候虽然大致明白各个硬件的组合 但是在跳线的环节可以难住了不少的人 也挡住了不少小白用户前进的脚步 确实机箱内部
  • 强化学习算法 DDPG 解决 CartPole 问题,代码逐条详解

    本文内容源自百度强化学习 7 日入门课程学习整理 感谢百度 PARL 团队李科浇老师的课程讲解 使用DDPG解决连续控制版本的CartPole问题 给小车一个力 连续量 使得车上的摆杆倒立起来 文章目录 一 安装依赖 二 导入依赖 三 设置