背包,子集和以及 (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 启动微服务 设置 run dashboard

    微服务如果很多,启动时如果在run窗口,会不是很方便,所以idea中配置了rundashboard,有时不自动出现时,需要进行配置: 配置操作如下: 我的idea版本2020.2 1.在父工程的.id ...

  2. DOM节点详解

    @ 目录 学习总结 1. 什么是 DOM 2. HTMLDOM 3. 元素获取 元素获取方式: 元素节点的属性操作 4. Node 对象的属性和方法 常用属性 常用方法 5. 事件处理 事件驱动编程 ...

  3. Idea中创建maven项目(超详细)

    Idea中创建maven项目 提示:前提条件时maven已经安装好,并且环境变量也配置完成,maven没安装好或者环境变量没有配置好的请参考我上一篇文章--maven的安装和配置 上篇博文链接:htt ...

  4. Qt 实现配置 OpenCV 环境,并实现打开图片与调用摄像头

    一.说明 所用QT版本:5.9.1 电脑配置:win10,64位系统 调用的是编译好的:OpenCV-MinGW-Build-4.1.0(稍后放链接) 在大学期间,由于项目需求需要用到QT+openc ...

  5. 【C++】二叉树的遍历(前中后)- 迭代法

    力扣题目:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/ 今天自己琢磨了很久如何不用递归将二叉树的遍历写出来,于是乎写出 ...

  6. 文档——STM32F10中文参考手册

    ST官方免费的资料.进入官方,第一个就是. 大家不用在CSDN付费下载了!!!!. (https://www.stmcu.org.cn/document/list/index/category-158 ...

  7. win10设置开机自启动程序

    问题情境:前两天刚刚给自己的win10系统美化了一下,但发现一个问题,每次开机都需要双击启动一个程序,才能达到一个我想要的效果,所以就在思考能不能将这个程序设为开机自启动项呢? 1.首先,找到启动文件 ...

  8. centos7 安装樱桃树cherrytree

    樱桃树对于做笔记或者编程来说都是很好的工具.以前再网上找了很久还是稿不懂cherrytree的方法.后来才发现,其实根本就不用那么麻烦.直接在epel源里面安装句可以了. 下面说下安装步骤: 第一步: ...

  9. echarts饼图去除圈外指向横线

    series: [ { name: '实时人员信息', type: 'pie', radius: ['86%', '80%'], avoidLabelOverlap: false, label: { ...

  10. 使用IntelliJ IDEA创建Java项目

    准备: Intelliyu IDEA 下载好JDK1.8 方法一: 方法二