背包,子集和以及 (max, +) 卷积在特殊情形下的求法

子集和 1:总重量不太大

有 \(n\) 个物品,每个物品重量为 \(w_i\),且 \(\sum\limits_{i} w_i=C\)。你需要对于 \(k\in [1,C]\) 均求出是否存在子集和 \(=k\)。

时间复杂度 \(\mathcal O(\frac{C\sqrt{C}}{\omega})\),空间复杂度 \(\mathcal O(n+\frac{C}{\omega})\)。

我们对于相同重量的物品二进制分组,然后暴力 01 背包,用 bitset 加速即可。

时间复杂度证明:

不妨设重量为 \(w\) 的物品有 \(a\) 个,则 \(\sum\limits_{i=1}^{m} w_ia_i=C\)。二进制拆分后的物品数为 \(\sum\limits_{k=0}\sum\limits_{i=1}^{m} [a_i\ge 2^k]\)。

对于固定的 \(k\),满足 \([a_i\ge 2^k]\) 的 \(i\) 有 \(\sqrt{\frac{C}{2^k}}\) 个,因此物品数 \(\sum\limits_{k}\sqrt{\frac{C}{2^k}}=\sqrt{C}\sum\limits_{k}2^{-k/2}\le \frac{\sqrt{2}}{\sqrt{2}-1}\sqrt{C}\)。


子集和 2:单个重量不太大

有 \(n\) 个物品,每个物品重量为 \(w_i\),满足 \(w_i\le D\)。问是否存在子集和 \(=C\)。

时间复杂度 \(\mathcal O(nD)\),空间复杂度 \(\mathcal O(n+D)\)时间复杂度 \(\mathcal O(\frac{n\sqrt{n}D}{\omega})\),空间复杂度 \(\mathcal O(n+\frac{\sqrt{n}D}{\omega})\)

法一:

先找到最大的 \(k\) 满足 \(\sum\limits_{i=1}^{k} w_i\le C\),问题转化为能否从 \(\{-w_1,\cdots,-w_k,w_{k+1},\cdots,w_n\}\) 选出子集和 \(C-\sum\limits_{i=1}^{k}w_i\)。该做法的核心思想是:如果当前子集和 \(>C\),那么从 \(w_1\sim w_k\) 中选一些数减到 \(\le C\),否则从 \(w_{k+1}\sim w_n\) 中选一些数加到 \(>C\)。

我们定义 \(\text{can}(tot,l,r)\) 表示是否存在 \(\lambda_{l},\lambda_{l+1},\cdots,\lambda_{r}=\{0,1\}\) 满足 \(\sum\limits_{i=1}^{l-1}w_i+\sum\limits_{i=l}^{r} \lambda_iw_i=tot\)。

性质 1:固定 \(tot,r\),则 \(\text{can}(tot,l,r)=1\) 的 \(l\) 为一段前缀。

我们定义 \(dp_{tot,r}\) 表示最大的 \(l\) 满足 \(\text{can}(tot,l,r)=1\)(如不存在,\(dp=-1\))。考虑转移。

性质 2:固定 \(tot,l\),则 \(\text{can}(tot,l,r)=1\) 的 \(r\) 为一段后缀。

据此有 \(dp_{tot,r}\le dp_{tot,r+1}\),于是有三类转移:

  • \(dp_{tot+w_{r+1},r+1}\leftarrow dp_{tot,r}\)
  • \(dp_{tot,r+1}\leftarrow dp_{tot,r}\)
  • \(dp_{tot-w_{l'},r}\leftarrow l'\ (l'\in [1,dp_{tot,r}))\)

我们发现第三类转移有 \(\mathcal O(n)\) 条,但是对于固定的 \(tot\),我们在 \(dp_{tot,r}\) 时有意义的转移只有 \(l'\in [dp_{tot,r-1},dp_{tot,r})\),否则可以在 \(dp_{tot,r-1}\) 的时候就转移掉。

因此,对于固定的 \(tot\),第三类转移总共有 \(\mathcal O(n)\) 条,因此时间复杂度是均摊 \(\mathcal O(nD)\) 的。

法二:

考虑随机打乱这个集合,则过程中期望达到的最值为 \(\mathcal O(\sqrt{n}D)\),用 bitset 加速即可。


(max, +) 卷积

给定两个长为 \(n\) 的序列 \(A,B\),求它们的 \((max,+)\) 卷积 \(C\)。保证 \(B\) 是凸函数。

时间复杂度 \(\mathcal O(n\log n)\) 或 \(\mathcal O(n)\),空间复杂度 \(\mathcal O(n)\)。

法一:

我们记 \(C_i\) 的决策位置(即 \(B\) 序列位置)为 \(f_i\),容易证明 \(f_{i-1}\le f_i\)。因此直接分治即可。

时间复杂度 \(\mathcal O(n\log n)\),空间复杂度 \(\mathcal O(n)\)。

法二:

考虑构建一个 \((2n-1)\times n\) 的矩阵 \(X\),满足 \(X_{i,j}=A_i+B_{i-j}\)。我们想要的即为 \(X\) 的每行最小值。

由于 \(B\) 是凸的,所以 \(X\) 是完全单调矩阵,用 SMAWK 求解即可。

不过听 Froggy 说 SMAWK 的效率被二分栈 / 分治吊打,所以可能 not practical。

时间复杂度 \(\mathcal O(n)\),空间复杂度 \(\mathcal O(n)\)。


01 背包:单个重量不太大

有 \(n\) 个物品,每个物品重量为 \(w_i\),价值为 \(v_i\),不同的 \(w_i\) 有 \(D\) 个。选出最大的子集 \(S\) 满足重量和不超过 \(C\),且总价值最大。

时间复杂度 \(\mathcal O(n\log n+DC\log C)\) 或 \(\mathcal O(n\log n+DC)\),空间复杂度 \(\mathcal O(n+C)\)。

对于相同 \(w\) 的物品,我们肯定将 \(v\) 从大到小贪心取,图像为一个凸函数。因此我们将背包在模 \(C\) 意义下分别做 \((max,+)\) 卷积即可。


完全背包:单个重量不太大

有 \(n\) 个物品,每个物品重量为 \(w_i\),价值为 \(v_i\),满足 \(w_i\le D\)。选出最大的可重子集 \(S\) 满足重量和不超过 \(C\),且总价值最大。

时间复杂度 \(\mathcal O(D^2\log C)\),空间复杂度 \(\mathcal O(n+D)\)。

注意到对于 \(i>D\),有 \(dp_i=\max\limits_{j+k=i} (dp_j+dp_k)\),且如果 \(|j-k|>D\),我们始终可以调整得到 \(|j-k|\le D\)。

因此通过 \([dp_{j-\frac{D}{2}},\cdots,dp_{j+\frac{D}{2}}]\) 以及 \([dp_{k-\frac{D}{2}},\cdots,dp_{k+\frac{D}{2}}]\),可以暴力卷积得到 \(dp_{j+k}\) 的值。

现在,假如我们知道了 \([dp_{k-D},\cdots,dp_{k+D}]\),它卷自己可以得到 \([dp_{2k-D},\cdots,dp_{2k+D}]\)。因此采用倍增的形式可以快速计算出 \([dp_{C-D},\cdots,dp_{C}]\),答案即为其中的最大值。

初始化的地方,暴力计算 \([dp_0,\cdots,dp_{2D}]\) 即可。

背包,子集和以及 (max, +) 卷积在特殊情形下的求法的更多相关文章

  1. 直接抱过来dd大牛的《背包九讲》来做笔记

    P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...

  2. HDU 3535 AreYouBusy (混合背包)

    题意:给你n组物品和自己有的价值s,每组有l个物品和有一种类型: 0:此组中最少选择一个 1:此组中最多选择一个 2:此组随便选 每种物品有两个值:是需要价值ci,可获得乐趣gi 问在满足条件的情况下 ...

  3. UESTC 424 AreYouBusy --混合背包

    混合三种背包问题. 定义:dp[i][k]表示体积为k的时候,在前i堆里拿到的最大价值. 第一类,至少选一项,dp初值全赋为负无穷,这样才能保证不会出现都不选的情况.dp[i][k] = max(dp ...

  4. Uva 12563,劲歌金曲,01背包

    题目链接:https://uva.onlinejudge.org/external/125/12563.pdf 题意:n首歌,每首歌的长度给出,还剩 t 秒钟,由于KTV不会在一首歌没有唱完的情况下切 ...

  5. HDU 5234 Happy birthday --- 三维01背包

    HDU 5234 题目大意:给定n,m,k,以及n*m(n行m列)个数,k为背包容量,从(1,1)开始只能往下走或往右走,求到达(m,n)时能获得的最大价值 解题思路:dp[i][j][k]表示在位置 ...

  6. 卷积神经网络CNN全面解析

    卷积神经网络(CNN)概述 从多层感知器(MLP)说起 感知器 多层感知器 输入层-隐层 隐层-输出层 Back Propagation 存在的问题 从MLP到CNN CNN的前世今生 CNN的预测过 ...

  7. uva 11825 Hackers' Crackdown (状压dp,子集枚举)

    题目链接:uva 11825 题意: 你是一个黑客,侵入了n台计算机(每台计算机有同样的n种服务),对每台计算机,你能够选择终止一项服务,则他与其相邻的这项服务都终止.你的目标是让很多其它的服务瘫痪( ...

  8. 第十三章——卷积神经网络(CNN)

    卷积神经网络(Convolutional neural networks,CNNs)来源于对大脑视觉皮层的研究,并于1980s开始应用于图像识别.现如今CNN已经在复杂的视觉任务中取得了巨大成功,比如 ...

  9. HDU 2602 Bone Collector 骨头收集者【01背包】

    题目链接:https://vjudge.net/contest/103424#problem/A 题目大意: 第一行输入几组数据,第二行第一个数字代表物体个数,第二个数代表总体积.需要注意的是,第三排 ...

随机推荐

  1. 解决IDEA中控制台输出乱码

    1. 修改VM Options(2种方法) 第一种,直接修改Tomcat中的 VM Options,这种只对当前项目有效 (1)先点击 Run -> Edit Configurations- 2 ...

  2. 小程序申请测试appid

    话不多说,直接上图:  1. 登录微信官方文档: https://developers.weixin.qq.com/miniprogram/dev/devtools/sandbox.html  2. ...

  3. EMS已有用户分配邮箱方法

    案例任务:已有域用户"test100",为该用户分配邮箱. 分配邮箱前,使用"get-user"命令确认用户类型.域用户"test100"的 ...

  4. 消息中间件MQ的学习境界和路线

    在<深入理解Java类加载机制,再也不用死记硬背了>里我提到了对于一门语言的"会"的三个层次.本篇将以知识地图的形式展现学习消息中间件MQ各个层次要掌握的内容. 知识地 ...

  5. victoriaMetrics库之布隆过滤器

    victoriaMetrics库之布隆过滤器 代码路径:/lib/bloomfilter 概述 victoriaMetrics的vmstorage组件会接收上游传递过来的指标,在现实场景中,指标或瞬时 ...

  6. PyQt5 基本语法(四)

    目录 2. 输入控件(一) 2.1 纯键盘 2.1.1 QLineEdit 2.1.1.1 描述 2.1.1.2 控件创建 2.1.1.3 输出模式 2.1.1.4 提示字符串 2.1.1.5 清空按 ...

  7. LC-206

    206. 反转链表 迭代法 class Solution { public ListNode reverseList(ListNode head) { //申请节点,pre和 cur,pre指向nul ...

  8. 安全开发运维必备,如何进行Nginx代理Web服务器性能优化与安全加固配置,看这篇指南就够了

    本章目录 1.引言 1.1 目的 1.2 目标范围 1.3 读者对象 2.参考说明 2.1 帮助参考 2.2 参数说明 3.3 模块说明 3.服务优化 3.1 系统内核 3.2 编译优化 3.3 性能 ...

  9. 关于visualvm无法监控本地java进程

    https://blog.csdn.net/weixin_43827693/article/details/105990675?spm=1001.2101.3001.6661.1&utm_me ...

  10. React 父组件调用子组件的方法

    父组件调用子组件的方法 React v16.3.0 及以后版本使用 import React, {Component} from 'react'; export default class Paren ...