zoukankan      html  css  js  c++  java
  • 「算法笔记」背包问题解题思路

    本文中,约定物品个数为 (n),背包的最大价值为 (m)

    多重背包问题的转化

    1. 可以通过把一个多重背包中的物品拆成多个 (01) 背包中的物品(每次大小翻倍,最后余下的单独拆出一个物品)。插入一个物品的复杂度为 (O(m imes log m))。比较好写,较常用。
    2. 可以使用单调队列来优化 ( ext{DP}),插入一个物品的复杂度为 (O(m))。比较难写,卡常时用。

    完全背包的特殊性质

    1. 对于物品集合 (A) 和物品集合 (B)(A igcup B) 的完全背包就等于 (A) 的完全背包和 (B) 的完全背包合并的结果。
    2. 如果有多个大小相同的物品,肯定是取价值最大的物品最优。

    任意背包的通用思路

    1. 合并两个背包的时间复杂度是 (O(m^2)),而加入一个物品的复杂度是 (O(m)) 左右。于是解决问题时,我们尽量避免合并两个背包。
    2. 如果只计算每种体积是否可以达到,可以用 ( ext{bitset}) 进行常数优化。
    3. 如果计算方案数,背包可以删除物品,否则不行。

    例题试炼

    例题一:

    (q) 个询问。每次问区间 ([l, r]) 的完全背包。强制在线。

    (n, q le 10^5, m le 30)

    线段树维护区间大小为 (k (1 le k le m)) 的最大价值,对于每个询问做完全背包即可。时间复杂度 (O(n imes log n imes m + q imes m^2))

    例题二:

    询问对于 (1 le i le n),除了第 (i) 个物品以外的物品的 (01) 背包。

    (n, m le 3000)

    分治,递归到左半边时加入右半边的物品,递归到右半边时加入左半边的物品。时间复杂度 (O(n imes log n imes m))

    例题三:

    一棵树,每个点都是物品。(q) 次询问,每次询问两点路径 (01) 背包。

    (n, q le 10^5, m le 30)

    直接树上倍增需要合并背包,效率低下。考虑点分治,对于 ( ext{DFS}) 只需加单个物品,处理询问时只需合并两个背包。时间复杂度 (O(n imes log n imes m + q imes m^2))

    “记录算法学习的点点滴滴”
  • 相关阅读:
    20120109_1
    .NET(C#)开源代码分析
    Vue filter API All In One
    js 千位分隔符 All In One
    css fontfeaturesettings All In One
    vue 子组件不使用 watch 如何更新组件 All In One
    miro whiteboard All In One
    转载:sql注入的危害(登陆并获取数据库的名字,表的名称和字段)
    Windows 7/windows server 2008 R2 64位版IIS不能连接Access数据库,80004005报错的解决办法
    LINQ如何做SELECT TOP操作
  • 原文地址:https://www.cnblogs.com/blog-of-xianglingao/p/10409814.html
Copyright © 2011-2022 走看看