决策单调性优化dp

四边形不等式

定义

若函数 \(w(x,y)(\mathbb{Z} \times \mathbb{Z} \rightarrow \mathbb{Z})\) 对于 \(\forall a,b,c,d \in \mathbb{Z}\) ,其中 \(a \leq b \leq c \leq d\) ,都有 \(w(a,d)+w(b,c) \geq w(a,c)+w(b,d)\),则称函数 \(w\) 满足四边形不等式

也就是交叉小于包含

这是四边形不等式最基本的定义。但是在做题中我们常常遇到下面的一种形式.

推论

若函数 \(w(x,y)(\mathbb{Z} \times \mathbb{Z} \rightarrow \mathbb{Z})\) 对于 \(\forall a,b \in \mathbb{Z}\) ,其中 \(a<b\) ,都有 \(w(a,b+1)+w(a+1,b) \geq w(a,b)+w(a+1,b+1)\) ,则称函数 \(w\) 满足四边形不等式

证明:

对于 \(a<c\) ,有:

\[w(a,c+1)+w(a+1,c)\ge w(a,c)+w(a+1,c+1) \]

对于 \(a+1<c\) ,有:

\[w(a+1,c+1)+w(a+2,c)\ge w(a+1,c)+w(a+2,c+1)\]

两式相加,得:

\[w(a,c+1)+w(a+1,c)+w(a+1,c+1)+w(a+2,c)\ge w(a,c)+w(a+1,c+1)+w(a+1,c)+w(a+2,c+1) \]

整理得:

\[w(a,c+1)+w(a+2,c)≥w(a,c)+w(a+2,c+1) \]

以此类推,可得

\[\forall a \leq b \leq c,\ \ w(a,c+1)+w(b,c)\geq w(a,c)+w(b,c+1) \]

同理对第二个数做这样的证明,即可得到

\[\forall a \leq b \leq c \leq d, \ \ w(a,d)+w(b,c) \geq w(a,c)+w(b,d) \]

另外,如果函数 \(w\) 满足四边形不等式,我们也称它满足凸完全单调性,或者说它是凸函数。

决策单调性

对于类似于 \(f(i,j)=\max/\min(f(k-1,j-1)+W[k,i])\) 的dp转移式,若 \(k=k'\)\(f(i,j)\) 取到最优值,则称 \(k'\)\((i,j)\) 的决策点。由此可知决策点是关于 \((i,j)\) 的函数,定义 \(k(i,j)=k'\)

若有 \(\forall i,j\in [1,n], \exists n,s.t.i < j\Rightarrow k(i,x)\le k(j,x)\) ,则称该动态规划问题具有决策单调性。

并不是所有的动态规划问题都满足决策单调性,对于满足决策单调性的dp,我们可以采取一些方法来优化时间复杂度,以便快速获得答案。

四边形不等式与决策单调性

定理

\[f(i)=\min_{j=1}^{i-1}\{f(j)+w[j,i]\} \]

\(k(x)\) 表示状态 \(x\) 取到最优值时的决策(即 \(i\) ),则决策单调性表述为:

\[\forall i\le j,k(i)\le k(j) \]

当且仅当:

\[\\\forall i\le j,w[i,j]+w[i+1,j+1]\le w[i+1,j]+w[i][j+1] \]

该规律可以通过打表验证

证明

\(\forall i\in [1,n],j \in [0,k(i)-1]\) ,根据决策单调性的定义得:

\[f(k(i))+w[k(i),i] \leq f(j)+w[j,i] \ \ \ \ \ \ (1) \]

\(\forall i' \in[i+1,n]\) ,显然 \(j<k(i)<i<i'\) ,由于 \(w\) 满足四边形不等式,那么有

\[w(j,i')+w[k(i),i] \geq w[j,i]+w[k(i),i'] \]

移项,得

\[w[k(i),i']-w[k(i),i] \leq w(j,i')-w[j,i] \ \ \ \ \ \ (2) \]

\((1)+(2)\)

\[f(k(i))+w[k(i),i'] \leq f(j)+w(j,i') \]

那么对于 \(i'\) 来说,以 \(k(i)\) 作为 \(i'\) 的决策,比 \(j<k(i)\) 作为 \(i'\) 的决策更优。因此 \(f(i') (i'>i)\) 的最优决策不可能小于 \(k(i)\),即 \(k(i') \geq k(i)\). \(f\)有决策单调性

于是,我们得到了证明一个dp方程满足决策单调性的方法:

证明(da biao xia cai)权函数 \(w\) 满足四边形不等式

那么我们如何解决上面定理所描述的这一类问题呢?下面提供两种方法

二分法

使用一个栈来维护数据,栈内每个元素保存一个决策在当前最优决策表下的起始位置和终了位置,当插入一个新决策时,我们为了维护整个决策表的单调性,从后往前对于每一个老决策考虑以下两个步骤:

  1. 考虑老决策的起始位置上是否比新决策更劣,如果是,那么直接抛弃老决策,继续考虑下一个决策
  2. 如果老决策更优,那么在老决策的区间上二分分界点,然后让新决策入栈

由于一个决策最多只能进栈出栈一次,加上二分查找,时间复杂度是 \(O(n\log n)\)

分治法

当上面那个式子 \(f(i),f(j)\) 的那一维寻址连续时,即只会从 \(f(i-1)\rightarrow f(i)\) 时,这个转移是单调且可离线的,这时候采用分治法是一个更好的选择

\(\text{solve}(l,r,L,R)\) 表示已知 \(dp[l\sim r]\) 的最优决策点均在 \([L,R]\) 中,我们可以取 \([l,r]\) 的中点 \(\text{mid}\) ,然后暴力扫区间 \([L,R]\) 找到它的最优决策点 \(k\) ,接着分治 \(\text{solve}(l,mid,L,k),\text{solve}(mid+1,r,k,R)\) 即可

时间复杂度 \(O(n\log n)\)

决策单调性与单调队列

如果 \(w\) 函数满足下面这个性质

\[\forall i\le j< k,w[i,j]+w[j,k]=w[i,k] \]

那么我们就一定可以找到一个一元函数 \(W[x]\) 使得

\[w[i,j]=W[j]-W[i] \]

那么我们考虑下面的dp方程

\[f(x)=\min_{k=b[k]}^{x-1}\{f(k)-W[k]\}+W[x] \]

\(g(k)=f(k)-W[k]\),其中 \(b[x]\)\(x\) 不降

有一个显然的性质是,如果 \(\exists j\le k<x,s.t.~g(k)\le g(j)\) ,那么决策 \(j\) 就是没有意义的,也就是典型的"我比你小,还比你强,你要退役"的单调队列形式,具体来说,由于 \(b[x]\) 单调,\(j\) 又比 \(k\) 小,\(k\) 被包含在 \(j\) 的范围中,那么若 \(j\) 是合法的决策,就有 \(k\) 是合法的决策

所以我们考虑用一个单调队列来维护决策表(包括决策和 \(g(决策)\) 两个值),对于每一个状态 \(f(x)\) ,计算过程如下

  1. 队首元素不断出队,直到其处于 \(b[x]\sim x-1\)
  2. 取出队首元素作为 \(f(x)\) 的最优决策并把它计算出来
  3. 计算此时的 \(g(x)\) ,并把这个决策丢到队尾,维护单调队列的单调性
  4. 重复上述步骤

时间复杂度 \(\mathcal O(n)\)

P3195 [HNOI2008]玩具装箱 (二分)

题目

P 教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。

P 教授有编号为 \(1 \cdots n\)\(n\) 件玩具,第 \(i\) 件玩具经过压缩后的一维长度为 \(C_i\)

为了方便整理,P教授要求:

  • 在一个一维容器中的玩具编号是连续的。

  • 同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物。形式地说,如果将第 \(i\) 件玩具到第 \(j\) 个玩具放到一个容器中,那么容器的长度将为 \(x=j-i+\sum\limits_{k=i}^{j}C_k\)

制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为 \(x\),其制作费用为 \((x-L)^2\)。其中 \(L\) 是一个常量。P 教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过 \(L\)。但他希望所有容器的总费用最小。

\(1 \leq n \leq 5 \times 10^4\)\(1 \leq L \leq 10^7\)\(1 \leq C_i \leq 10^7\)

题解

\(f[i]\) 表示将前 \(i\) 个玩具装箱的最小花费,这道题可以很容易地写出一个转移方程:

\[f[i]=\min_{j=1}^{i-1}\{f[j]+w[j+1][i]\} \]

其中

\[w[i][j]=(j-i+\sum_{k=i}^jc[k]-L)^2 \]

证明左转洛谷题解区,实战中可以考虑使用打表来验证

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 50010
using namespace std;
ll n,L,l,r,mid,top,a[N],f[N],d[N],lt[N];
ll g(ll x, ll y)
{
	return f[x]+(y-x-1+a[y]-a[x]-L)*(y-x-1+a[y]-a[x]-L);
}
ll find(ll x)
{
	ll l=1,r=top;
	while(l<r)
	{
		ll mid=(l+r+1)>>1;
		if (x<lt[mid]) r=mid-1;
		else l=mid;
	}
	return d[l];
}
int main()
{
	scanf("%lld%lld",&n,&L);
	for (ll i=1;i<=n; ++i)
	{
		scanf("%lld",&a[i]);
		a[i]+=a[i-1]; 
	}
	lt[++top]=1;
	d[top]=0;
	for (ll i=1;i<=n;++i)
	{
		f[i]=g(find(i), i);
		while(top && g(i,lt[top])<g(d[top],lt[top])) top--;
		l=lt[top];
		r=n;
		while(l<r)
		{
			mid=(l+r)>>1;
			if(g(i,mid)<g(d[top],mid)) r=mid;
			else l=mid+1;
		}
		if(g(i,l)>g(d[top],l)) continue;
		d[++top]=i;
		lt[top]=l;
	}
	printf("%lld",f[n]);
    return 0;
}

[USACO08MAR]Land Acquisition G (二分)

题目

Farmer John 准备扩大他的农场,眼前他正在考虑购买 \(N\) 块长方形的土地。

如果 FJ 单买一块土地,价格就是土地的面积。但他可以选择并购一组土地,并购的价格为这些土地中最大的长乘以最大的宽。比如 FJ 并购一块 \(3 \times 5\) 和一块 \(5 \times 3\) 的土地,他只需要支付 \(5 \times 5=25\) 元, 比单买合算。

FJ 希望买下所有的土地。他发现,将这些土地分成不同的小组来并购可以节省经费。 给定每份土地的尺寸,请你帮助他计算购买所有土地所需的最小费用。

\(1 \leq N \leq 5 \times 10^4\),两个整数 \(w_i\)\(l_i\),代表第 \(i\) 块土地的长和宽。保证土地的长和宽不超过 \(10^6\)

题解

首先我们将土地按照长度排序,干掉一维,设 \(f[i]\) 表示考虑到第 \(i\) 个土地时的最小花费,那么容易写出转移方程如下:

\[f[i]=\min_{j=0}^{i-1}\{f[j]+(\max_{k=j+1}^iw[i])\times l[j+1]\} \]

通过打表我们知道这玩意是不满足决策单调性的,但我们通过分析题目可以得知,如果一片大土地完全包含住了某一个小土地,那么那一片小土地就是没有意义的,我们将所有的这种小土地删掉,发现剩余的 \(w[i]\) 是满足单调性的,是随着 \(l[i]\) 增大而减小的

因此我们可以将转移方程直接写成:

\[f[i]=\min_{j=0}^{i-1}\{f[j]+w[i]\times l[j+1]\} \]

此时这个转移式是满足决策单调性的,可以直接通过上面的定理证明

ybtoj 金牌导航 征途 (分治+方差题意转化)

题目

给定一个长度为 \(n\) 的非负整数序列,要求你把序列划分为 \(m\) 段,将每段数字求和得到 \(m\) 个数字,使得 \(m\) 个数的方差最小,假设方差是 \(v\) ,输出 \(v\times m^2\)

\(1\le m\le n\le 3000\)

题解

题目让我们求

\[m^2\times \frac{\sum_{i=1}^m(s_i-\frac{\text{sum}}{m})^2}{m} \]

化简可得

\[m\times \sum_{i=1}^ms_i^2-\text{sum}^2 \]

那么问题就转化成,将数列划分为 \(m\) 段,最小化和的平方和

\(f[i][j]\) 表示考虑到第 \(i\) 个数,划分了 \(j\) 段时的答案,我们显然有

\[f[i][j]\leftarrow \min_k(f[k][j-1]+(s[j]-s[k])^2) \]

可以发现这个式子 \(j\) 的那一维是符合分治法的,转移即可

代码如下:

void dp(int x,int l,int r,int L,int R) 
{
    int mid=l+r>>1,M=0;
    f[x][mid]=inf;
    for(int i=L;i<=R&&i<mid;i++)
    {
        int tmp=f[x-1][i]+(s[mid]-s[i])*(s[mid]-s[i]);
        if(tmp<f[x][mid])
            f[x][mid]=tmp,M=i;
    }
    if(l<mid)
        dp(x,l,mid-1,L,M);
    if(r>mid)
        dp(x,mid+1,r,M,R);
}

POI2011 避雷针 Lightning Conductor (分治+不等式条件转化)

题目

气候变化使 Byteburg 不得不建造一个大型避雷针来保护城市里的所有建筑物。建筑物恰好沿一条街,从 \(1\)\(n\) 编号。

建筑物的高度和避雷针的高度都是非负整数。Byteburg经费有限,只能建造一个避雷针。而且避雷针越高,价格越贵。

在建筑物 \(i\)(高度为 \(h_i\) )屋顶放置高为 \(p\) 的避雷针能够保护建筑物 \(j\) 的条件是:

\[h_j \le h_i + p - \sqrt{\lvert i - j \rvert} \]

其中 \(\lvert i - j \rvert\) 表示 \(i\)\(j\) 差的绝对值。

Byteburg 需要你帮它计算,如果在第 \(i\) 个建筑物的屋顶放置这样的避雷针的话,避雷针的最小高度 \(p_i\) 是多少。

\(1\le n\le 5\times 10^5\)

题解

首先我们可以将题目中给的那个不等式转化为

\[p_i=\max\{h_j+\sqrt{\lvert i-j\rvert}\}-h_i \]

绝对值通过分类讨论去掉,发现这个式子是具有决策单调性的,然后 \(p_i\) 与其他的 \(p\) 是没有关系的,因此分治解决即可

P1912 [NOI2009] 诗人小G (二分+方案输出)

题目

小 G 是一个出色的诗人,经常作诗自娱自乐。但是,他一直被一件事情所困扰,那就是诗的排版问题。

一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行中,注意一行中可以放的句子数目是没有限制的。小 G 给每首诗定义了一个行标准长度(行的长度为一行中符号的总个数),他希望排版后每行的长度都和行标准长度相差不远。显然排版时,不应改变原有的句子顺序,并且小 G 不允许把一个句子分在两行或者更多的行内。在满足上面两个条件的情况下,小 G 对于排版中的每行定义了一个不协调度, 为这行的实际长度与行标准长度差值绝对值的 \(P\) 次方,而一个排版的不协调度为所有行不协调度的总和。

小 G 最近又作了几首诗,现在请你对这首诗进行排版,使得排版后的诗尽量协调(即不协调度尽量小),并把排版的结果告诉他。

\(T\le 5,N\le 10^5,L\le 3\times 10^6,P\le 10\)

所有句子的长度不超过 \(30\)

题解

\(f[i]\) 表示考虑到第 \(i\) 个语句时的最小不协调度,我们定义 \(\text{pre}[i]\) 表示的是前 \(i\) 个句子的长度和,那么转移就是

\[f[i]=\min^{i-1}_{j=0}\{f[j]+|\text{pre}[i]-\text{pre[j]}-L|^P\} \]

然后这个东西是有决策单调性的,打表猜测即可

方案输出只需要记住每一个状态的决策点就行了

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

P4381 [IOI2008] Island (基环树+树形dp+单调队列优化)

题目

你准备浏览一个公园,该公园由 \(N\) 个岛屿组成,当地管理部门从每个岛屿 \(i\) 出发向另外一个岛屿建了一座长度为 \(L_i\) 的桥,不过桥是可以双向行走的。同时,每对岛屿之间都有一艘专用的往来两岛之间的渡船。相对于乘船而言,你更喜欢步行。你希望经过的桥的总长度尽可能长,但受到以下的限制:

  • 可以自行挑选一个岛开始游览。
  • 任何一个岛都不能游览一次以上。
  • 无论任何时间,你都可以由当前所在的岛 \(S\) 去另一个从未到过的岛 \(D\)。从 \(S\)\(D\) 有如下方法:
    • 步行:仅当两个岛之间有一座桥时才有可能。对于这种情况,桥的长度会累加到你步行的总距离中。
    • 渡船:你可以选择这种方法,仅当没有任何桥和以前使用过的渡船的组合可以由 \(S\) 走到 \(D\) (当检查是否可到达时,你应该考虑所有的路径,包括经过你曾游览过的那些岛)。

注意,你不必游览所有的岛,也可能无法走完所有的桥。

请你编写一个程序,给定 \(N\) 座桥以及它们的长度,按照上述的规则,计算你可以走过的桥的长度之和的最大值。

对于 \(100\%\) 的数据,\(2\leqslant N\leqslant 10^6,1\leqslant L_i\leqslant 10^8\)

保证每个岛都有桥与之相连

题解

首先,这道题是一个基环树森林,因此可以采用BFS的方法找到所有的连通分量,我们对每一个连通分量考虑,若无环,那么就是一个简单的树形dp;如果有环,那么我们先找到环,然后破环为链,设 \(g[x]\) 表示 \(x\) 点向外向树上最远可延伸的距离,设 \(f[x]\) 表示经过以 \(x\) 为根的外向树的最长距离, \(dis[i][j]\) 表示链上 \(i,j\) 之间的距离

转移方程如下:

\[f[x]=\max_{i=x-n+1}^{x-1}\{g[i]+g[x]+dis[i][x]\} \]

由于 \(dis[i][k]=dis[i][j]+dis[j][k]\) ,所以满足我们上面所述的单调队列模型,套用计算即可

时间复杂度 \(\mathcal O(n)\)

posted on 2023-07-24 19:58  star_road_xyz  阅读(23)  评论(0编辑  收藏  举报

导航