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))

    “记录算法学习的点点滴滴”
  • 相关阅读:
    oracle 10g 免安装客户端在windows下配置
    sql2005 sa密码
    使用windows live writer 有感
    windows xp SNMP安装包提取
    汉化groove2007
    迁移SQL server 2005 Reporting Services到SQL server 2008 Reporting Services全程截图操作指南
    foxmail 6在使用中的问题
    AGPM客户端连接不上服务器解决一例
    SpringSource Tool Suite add CloudFoundry service
    Java 之 SWing
  • 原文地址:https://www.cnblogs.com/blog-of-xianglingao/p/10409814.html
Copyright © 2011-2022 走看看