wqs二分学习笔记

wqs二分适用题目及理论分析

wqs二分可以用来解决这类题目:

给你一个强制要求,例如必须\(n\)条白边,或者划分成\(n\)段之类的,然后让你求出最大(小)值。但是需要满足图像是个凸包。

这里讲一下它的原理。假设我们现在需要解决的问题是求分\(x\)段的最小花费。我们假设对于每个\(x\)它的最小花费\(f(x)\)的图像长成这个样子:

当然,这只是个大概图像。

我们假设拿一条斜率为\(k\)的直线去切它,我们假设切到的截距最大值为\(g(k)\),使截距最大点为\(n\),那么图像大概长成这个样子。

我们显然可以得到一个式子:

\[f(n)=kn+g(k)
\]
\[\Rightarrow g(k)=f(n)-kn
\]

于是,我们只需要知道\(g(k)\)和\(n\)就可以求出\(f(n)\)。

我们观察\(g(k)\)的式子,发现其实就等价于每分一段贡献在原有的基础上少\(k\)(对于这个问题而言),于是我们可以忽略段数限制,直接做\(\texttt{dp}\),就可以找到最小截距和\(n\)。

我们为了满足恰好分成\(x\)段的要求,如果我们当前的\(n\)小了,我们就应该把\(k\)变小,反之亦凡,于是我们就可以使用二分查找到合适的\(k\)使得\(n=x\)从而计算出\(f(x)\)了。(这个应该很显然吧)

(所以谁能告诉我为什么可以不用二分小数啊???)

例题讲解

\(\text {The 1st}\)

忘情

题目描述

给你一个有\(n\)个数的数列,要求你分成\(m\)段,每一段的贡献为\((\sum a_i+1)^2\),求出最小贡献和。

解题思路

真的很经典(虽然最经典还是Tree I

如果没有恰好分成\(m\)段,我们可以轻易地列出\(\texttt{dp}\)式,即:

\[dp[i]=\min_{j=1}^{i-1}\{dp[j]+(pre[i]-pre[j]+1)^2\}
\]

其中\(pre[i]=\sum_{j=1}^{i} a_j\)。

现在有了分成\(m\)段的条件,我们发现只需要说明这是个凸函数就可以使用\(\texttt{wqs}\)二分了。这个感性证明一下就好了。然后使用斜率优化就可以做到\(\Theta(n\log w)\)。其中\(w\)是值域。

\(\text {Code}\)

代码戳这里打开

\(\text {The 2ed}\)

林克卡特树

题目描述

给定一棵\(n\)个点的数,再给定\(k\),求出树上不相交的\(k+1\)条链的权值最大和。需要注意的是,链是可以在树上拐个弯的。

解题思路

首先很显然这是个上凸函数。于是我们可以考虑使用\(\texttt{wqs}\)二分。为了方便,后面设\(v\)为\(\texttt{wqs}\)二分中的斜率。

考虑不考虑段数的\(dp\),我们可以设\(dp[u][0/1/2]\),表示\(u\)这个点与儿子之间有\(0/1/2\)条连边时以\(u\)为根的子树内所包含的链权值之和的最大值。

为了方便,\(dp[u][1]\)是还未构造完当前这条链的权值和,也就是说这个东西不需要减去\(v\)。

设:

\[k=\max \{dp[v][0],dp[v][1]-v,dp[v][2]\}
\]

可以得出\(dp\)式:

\[dp[u][2]\gets \max\{dp[u][2]+k,dp[u][1]+dp[v][1]+w-v\}
\]
\[dp[u][1]\gets \max\{dp[u][1]+k,dp[u][0]+dp[v][1]+w\}
\]
\[dp[u][0]\gets dp[u][0]+k
\]

注意开\(\text {long long}\)即可。

\(\text {Code}\)

代码戳这里打开

\(\text {The 3rd}\)

Gosha is hunting

解题思路

考虑最朴素的\(n^3\texttt{dp}\),可以设\(dp[i][j][k]\)表示前\(i\)个神奇宝贝用了\(j\)个宝贝球和\(k\)个超级球的最大期望捕捉个数。

容易得到转移式:

\[f[i][j][k]=\max\{f[i-1][j][k],f[i-1][j-1][k]+p[i],f[i-1][j][k-1]+u[i],f[i-1][j-1][k-1]|+p[i]+u[i]-p[i]\times u[i]\}
\]

我们发现如果我们固定\(j\),可以通过打表发现这其实是个凸函数,于是我们可以使用\(\texttt{wqs}\)二分做到\(\Theta(n^2\log n)\)。我们发现对于\(j\)也有同样的性质,所以我们可以\(\texttt{wqs}\)套\(\texttt{wqs}\)二分做到\(\Theta(n\log ^2 n)\)。

不过似乎概率都是\(1\)的时候会卡掉,因为它不是一个凸函数函数了,到后面是一个常函数了。但是这道题数据很水,所以还是没有被卡。

\(\text {Code}\)

代码戳这里打开

\(\text {The 4th}\)

题目传送门

题目大意

现在有\(n\)个村庄,你需要在里面选出\(k\)个作为邮局,使得每个村庄到其最近的邮局之和最小。

思路

这道题其实跟\(\text {The 1st}\)有些类似。

首先我们可以列出\(dp\)式,设\(dp[i][j]\)表示前面\(i\)个村庄选出\(j\)个作为邮局,那么,容易得到:

\[dp[i][j]=\min\{dp[k][j-1]+\texttt{cost}(k+1,i)\}
\]

其中\(\texttt{cost}(i,j)\)表示\(i\to j\)这段村庄选出一个作为邮局的最小距离和,不难想到选出来的村庄为中间点时最优,于是可以利用前缀和\(\Theta(1)\)求出。

那接下来应该怎么办呢?第一种办法就是平行四边形优化,但显然时间复杂度还是\(\Theta(n^2)\),虽然足以通过此题,但是不能满足我们对时间复杂度的渴望。第二种办法就是\(\texttt {wqs}\)二分。

感性理解一下,随着选出来的村庄的增多,那么,增长速度也会逐渐变慢。于是可以得到,当前函数为凸函数,也就可以用\(\texttt {wqs}\)二分。

那么,我们现在就可以得到\(dp\)式了:

\[dp[i]=\min\{dp[j]+\texttt{cost}(j+1,i)+\texttt{extra}\}
\]

其中\(\texttt {extra}\)表示额外花费。

我们惊奇地 通过打表 发现,这个东西是具有决策单调性的,于是,我们就可以使用决策单调栈优化了。

综上,时间复杂度为\(\Theta(n\log ^2n)\)。

\(\text {Code}\)

代码戳这里打开

\(\text{The 5th}\)

题目传送门

题目大意

给出 \(n,k\) , 将一个长度为 \(n\) 的序列分成 \(k\) 段,每一段的贡献是矩阵的一个子矩阵的区间和。求出最小划分贡献。

\(n\le 4000,0\le k\le \min(n,800)\)

思路

首先不难想到一个 \(\Theta(n^2k)\)的dp方法,我们设 \(f_{i,j}\) 表示前面 \(j\)分成 \(i\) 段的最小花费,可以得到转移式:

\[f_{i,j}=f_{i-1,k-1}+cost(k,j)
\]

其中 \(cost(k,j)\) 表示左上角为 \((k,k)\) 右下角为 \((j,j)\) 的子矩阵的和。

然后可以发现这个函数是个凸函数,因为它分得越多它的贡献肯定越小,而且它下降的速率肯定会越来越慢(感性理解),于是我们就可以使用\(\texttt {wqs}\)二分了,但是这样直接转移还是 \(\Theta(n^2\log w)\) ,其中 \(w\) 是值域,还不足以通过此题,然后我们通过打表发现决策点单调递增,于是我们就可以使用单调栈了。

wqs二分 学习笔记的更多相关文章

  1. [总结] wqs二分学习笔记

    论文 提出问题 在某些题目中,强制规定只能选 \(k\) 个物品,选多少个和怎么选都会影响收益,问最优答案. 算法思想 对于上述描述的题目,大部分都可以通过枚举选择物品的个数做到 \(O(nk^2)\ ...

  2. WQS二分学习笔记

    前言 \(WQS\)二分听起来是个很难的算法,其实学起来也并不是那么难. 适用范围 在某些题目中,会对于某个取得越多越优的物品,限定你最多选择\(k\)个,问你能得到的最优答案. 例如这道题目:[CF ...

  3. dp凸优化/wqs二分学习笔记(洛谷4383 [八省联考2018]林克卡特树lct)

    qwq 安利一个凸优化讲的比较好的博客 https://www.cnblogs.com/Gloid/p/9433783.html 但是他的暴力部分略微有点问题 qwq 我还是详细的讲一下这个题+这个知 ...

  4. p2619 [国家集训队2]Tree I [wqs二分学习]

    分析 https://www.cnblogs.com/CreeperLKF/p/9045491.html 反正这个博客看起来很nb就对了 但是不知道他在说啥 实际上wqs二分就是原来的值dp[x]表示 ...

  5. 一篇自己都看不懂的CDQ分治&整体二分学习笔记

    作为一个永不咕咕咕的博主,我来更笔记辣qaq CDQ分治 CDQ分治的思想还是比较简单的.它的基本流程是: \(1.\)将所有修改操作和查询操作按照时间顺序并在一起,形成一段序列.显然,会影响查询操作 ...

  6. CDQ分治与整体二分学习笔记

     CDQ分治部分 CDQ分治是用分治的方法解决一系列类似偏序问题的分治方法,一般可以用KD-tree.树套树或权值线段树代替. 三维偏序,是一种类似LIS的东西,但是LIS的关键字只有两个,数组下标和 ...

  7. 决策单调性&wqs二分

    其实是一个还算 trivial 的知识点吧--早在 2019 年我就接触过了,然鹅当时由于没认真学并没有把自己学懂,故今复学之( 1. 决策单调性 引入:在求解 DP 问题的过程中我们常常遇到这样的问 ...

  8. 「学习笔记」wqs二分/dp凸优化

    [学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...

  9. [学习笔记]凸优化/WQS二分/带权二分

    从一个题带入:[八省联考2018]林克卡特树lct——WQS二分 比较详细的: 题解 P4383 [[八省联考2018]林克卡特树lct] 简单总结和补充: 条件 凸函数,限制 方法: 二分斜率,找切 ...

随机推荐

  1. vue3.0入门(五):vite构建vue项目

    使用vite构建项目步骤 安装node,cmd输入:node -v验证是否安装成功:一般node安装后会自动安装npm,cmd输入:npm -v验证是否安装成功 选择一个文件夹作为项目文件夹,搜索框输 ...

  2. Java - 记录01_开发环境搭建

    时间:2017-07-04 记录:byzqy 一.什么是JDK JDK(Java Development Kit):Java开发工具集,即Java语言的软件开发工具包. SDK(Software De ...

  3. 分布式协调组件Zookeeper之 选举机制与ZAB协议

    Zookeeper简介: Zookeeper是什么: Zookeeper 是⼀个分布式协调服务的开源框架. 主要⽤来解决分布式集群中应⽤系统的⼀致性问题, 例如怎样避免同时操作同⼀数据造成脏读的问题. ...

  4. Hopper Disassembler系列之Sublime Text 3 爆破

    https://www.52pojie.cn/thread-793069-1-1.html 当参数少于7个时, 参数从左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9. 当参数 ...

  5. js基本数据类型之间的转换

    常见五大基本数据类型 1.number 2.string 3.boolean 4.undefined 5.null 一.转换为string ①调用toString() 方法 因为null和undefi ...

  6. XXE从0到1

    XXE从0到1 1. XXE概述 XXE(XML External Entity Injection)即XML外部实体注入.漏洞是在对不安全的外部实体数据进行处理时引发的安全问题. 下面我们主要介绍P ...

  7. 利用nginx 来实现内网yum源(反向代理)

    简介 在项目部署时,尤其是在政府企业,对于外网简直是奢望,但是对于运维来说,没有外网的话只能自建yum源.我今天来说的是一种简单的自建yum源方法,前提是必须有一台内外网都有的机器,我们一般称为前置机 ...

  8. python+echarts+flask实现对全国疫情数据的爬取并可视化展示

    用Python进行数据爬取并存储到数据库,3.15学习总结(Python爬取网站数据并存入数据库) - 天岁 - 博客园 (cnblogs.com) 通过echarts+flask实现数据的可视化展示 ...

  9. c++ undefined reference

    记录一次c++编程时发现的问题 报错 undefined reference undefined reference to `Student::~Student()' 下面还有类似的好几行,翻译过来就 ...

  10. # Zombie Gunship Survival(僵尸炮艇生存)GG修改器修改教程

    Zombie Gunship Survival(僵尸炮艇生存)GG修改器修改教程 1.修改伤害,打击范围,武器冷却时间,子弹容量 测试手机机型:华为畅享7 系统版本:Android7.0 是否ROOT ...