简单四边形不等式优化dp(下)

广义决策单调性

强烈推荐题解视频

f k , i f_{k,i} fk,i表示前 i i i个村庄放了 k k k个邮局的最小代价。

f k , i = min ⁡ j = 0 i { f k − 1 , j + w j + 1 , i } f_{k,i}=\overset{i}{\underset{j=0}\min}\{f_{k-1,j}+w_{j+1,i}\} fk,i=j=0mini{fk1,j+wj+1,i}
表示分配给村庄 [ j + 1 , i ] [j+1,i] [j+1,i]一个邮局。

f 0 , 0 = 0 f_{0,0}=0 f0,0=0,其他状态为正无穷。就是 O ( n 3 ) O(n^3) O(n3)

贡献函数 w i , j w_{i,j} wi,j表示给村庄 [ i , j ] [i,j] [i,j]分配一个邮局的最小贡献。
显然邮局放在区间下标中位数对应的村庄最优。如果有偶数个村庄放在两个中位数处都可以。
因为如果向着远离中位数的地方移动,那么减少的贡献少,而增加的贡献多。

w i , j = w i , j − 1 + a j − a ⌊ i + j 2 ⌋ w_{i,j}=w_{i,j-1}+a_j-a_{\left\lfloor \frac {i+j}2\right\rfloor} wi,j=wi,j1+aja2i+j
因为当区间长度由奇数向偶数转移时中位数不变,式子肯定成立。
而区间长度为偶数时可以认为邮局位于右边那个中位数处,中位数也可以认为不变。

打表打出决策单调性,于是可以 O ( n 2 ) O(n^2) O(n2)
f k , i = min ⁡ j = p k − 1 , i p k , i + 1 { f k − 1 , j + w j + 1 , i } f_{k,i}=\overset{p_{k,i+1}}{\underset{j=p_{k-1,i}}\min}\{f_{k-1,j}+w_{j+1,i}\} fk,i=j=pk1,iminpk,i+1{fk1,j+wj+1,i}

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3e3;
int a[N+5];
int w[N+5][N+5];
int f[305][N+5],p[305][N+5];
int main() {
	int n,K;
	cin>>n>>K;
	for(int i=1; i<=n; i++) cin>>a[i];
	for(int i=1; i<=n; i++)
		for(int j=i; j<=n; j++)
			w[i][j]=w[i][j-1]+a[j]-a[i+j>>1];
	for(auto&i:f) for(auto&j:i) j=1e9;
	f[0][0]=0;
	for(int i=1;i<=K;i++) p[i][n+1]=n;注意最优决策点要有初值
	for(int k=1; k<=K; k++)
		for(int i=n; i; i--)因为在枚举i时用到的i+1的最优决策点,因此要倒序枚举
			for(int j=p[k-1][i]; j<=p[k][i+1]; j++)
//			for(int j=0; j<=i-1; j++)
				if(f[k][i]>f[k-1][j]+w[j+1][i])
					f[k][i]=f[k-1][j]+w[j+1][i],p[k][i]=j;
//				f[k][i]=min(f[k][i],f[k-1][j]+w[j+1][i]);
	cout<<f[K][n]<<endl;
//	for(int k=1;k<=K;k++,cout<<endl)
//		for(int i=1;i<=n;i++,cout<<' ')
//			cout<<p[k][i];
}

证明决策单调性还是老三样:

  1. 证明贡献函数满足四边形不等式:
    带入递推式 w i , j = w i , j − 1 + a j − a ⌊ i + j 2 ⌋ w_{i,j}=w_{i,j-1}+a_j-a_{\left\lfloor \frac {i+j}2\right\rfloor} wi,j=wi,j1+aja2i+j就会发现贡献函数显然满足四边形不等式:
    w i , j + w i + 1 , j + 1 ≤ w i , j + 1 + w i + 1 , j w_{i,j}+\textcolor{blue}{w_{i+1,j+1}}\leq \textcolor{red}{w_{i,j+1}}+w_{i+1,j} wi,j+wi+1,j+1wi,j+1+wi+1,j
    w i , j + w i + 1 , j + w i + 1 , j + a j + 1 − a ⌊ i + j − 2 2 ⌋ ≤ w i , j + a j + 1 − a ⌊ i + j − 1 2 ⌋ + w i + 1 , j w_{i,j}+\textcolor{blue}{w_{i+1,j}+w_{i+1,j}+a_{j+1}-a_{\left\lfloor{\frac{i+j-2}{2}}\right\rfloor}}\leq \textcolor{red}{w_{i,j}+a_{j+1}-a_{\left\lfloor{\frac{i+j-1}{2}}\right\rfloor}}+w_{i+1,j} wi,j+wi+1,j+wi+1,j+aj+1a2i+j2wi,j+aj+1a2i+j1+wi+1,j
  2. 证明状态函数满足四边形不等式:
    不需要归纳,直接设 p i , j + 1 = x , p i + 1 , j = y p_{i,j+1}=x,p_{i+1,j}=y pi,j+1=x,pi+1,j=y,我们讨论 x < y x<y x<y的情况:
    两个含有 f i , j , f i + 1 , j + 1 \color{blue}f_{i,j},f_{i+1,j+1} fi,j,fi+1,j+1的不等式:
    { f i , j ≤ f i − 1 , x + w x + 1 , j              f i + 1 , j + 1 ≤ f i , y + w y + 1 , j + 1 \left\{\begin{matrix} {\color{blue}{f_{i,j}}}\leq f_{i-1,x}+w_{x+1,j}\;\;\;\;\;\;\\ \textcolor{blue}{f_{i+1,j+1}}\leq f_{i,y}+w_{y+1,j+1} \end{matrix}\right. {fi,jfi1,x+wx+1,jfi+1,j+1fi,y+wy+1,j+1
    加起来: f i , j + f i + 1 , j + 1 ≤ f i − 1 , x + w x + 1 , j + f i , y + w y + 1 , j + 1 \textcolor{blue}{f_{i,j}+f_{i+1,j+1}}\leq f_{i-1,x}+w_{x+1,j}+f_{i,y}+w_{y+1,j+1} fi,j+fi+1,j+1fi1,x+wx+1,j+fi,y+wy+1,j+1
    再加上两个含有 f i , j + 1 , f i + 1 , j \color{red}f_{i,j+1},f_{i+1,j} fi,j+1,fi+1,j的等式
    { f i , j + 1 = f i − 1 , x + w x + 1 , j + 1 f i + 1 , j = f i , y + w y + 1 , j                \left\{\begin{matrix} {\color{red}f_{i,j+1}}=f_{i-1,x}+w_{x+1,j+1}\\ {\color{red}f_{i+1,j}}=f_{i,y}+w_{y+1,j}\;\;\;\;\;\;\; \end{matrix}\right. {fi,j+1=fi1,x+wx+1,j+1fi+1,j=fi,y+wy+1,j
    加到不等式的右边去:
    f i , j + f i + 1 , j + 1 + f i − 1 , x + w x + 1 , j + 1 + f i , y + w y + 1 , j ≤ f i , j + 1 + f i + 1 , j + f i − 1 , x + w x + 1 , j + f i , y + w y + 1 , j + 1 \textcolor{blue}{f_{i,j}+f_{i+1,j+1}}+f_{i-1,x}+w_{x+1,j+1}+f_{i,y}+w_{y+1,j}\leq {\color{red}f_{i,j+1}}+{\color{red}f_{i+1,j}}+f_{i-1,x}+w_{x+1,j}+f_{i,y}+w_{y+1,j+1} fi,j+fi+1,j+1+fi1,x+wx+1,j+1+fi,y+wy+1,jfi,j+1+fi+1,j+fi1,x+wx+1,j+fi,y+wy+1,j+1
    f i , j + f i + 1 , j + 1 + w x + 1 , j + 1 + w y + 1 , j ≤ f i , j + 1 + f i + 1 , j + w x + 1 , j + w y + 1 , j + 1 \textcolor{blue}{f_{i,j}+f_{i+1,j+1}}+w_{x+1,j+1}+w_{y+1,j}\leq {\color{red}f_{i,j+1}}+{\color{red}f_{i+1,j}}+w_{x+1,j}+w_{y+1,j+1} fi,j+fi+1,j+1+wx+1,j+1+wy+1,jfi,j+1+fi+1,j+wx+1,j+wy+1,j+1
    对不等式左边用贡献函数的四边形不等式:
    f i , j + f i + 1 , j + 1 + w x + 1 , j + w y + 1 , j + 1 ≤ f i , j + 1 + f i + 1 , j + w x + 1 , j + w y + 1 , j + 1 {f_{i,j}+f_{i+1,j+1}}+w_{x+1,j}+w_{y+1,j+1}\leq {f_{i,j+1}}+{f_{i+1,j}}+w_{x+1,j}+w_{y+1,j+1} fi,j+fi+1,j+1+wx+1,j+wy+1,j+1fi,j+1+fi+1,j+wx+1,j+wy+1,j+1
    约掉了:
    f i , j + f i + 1 , j + 1 ≤ f i , j + 1 + f i + 1 , j {f_{i,j}+f_{i+1,j+1}}\leq {f_{i,j+1}}+{f_{i+1,j}} fi,j+fi+1,j+1fi,j+1+fi+1,j
    证毕。(另一种情况同理)
  3. 证明决策单调性:
    打出表来会知道决策单调性是 p i − 1 , j ≤ p i , j ≤ p i , j + 1 p_{i-1,j}\leq p_{i,j}\leq p_{i,j+1} pi1,jpi,jpi,j+1
    接下来证明左边,假设不成立,设 p i , j = p , p i − 1 , j = k p_{i,j}=p,p_{i-1,j}=k pi,j=p,pi1,j=k,则: p < k p<k p<k
    先写出两个决策点在 f i − 1 , j f_{i-1,j} fi1,j意义下的最优性:
    A : f i − 1 , k ≤ f i − 1 , p A:f_{i-1,k}\leq f_{i-1,p} A:fi1,kfi1,p
    再写出我们期望它们在 f i , j f_{i,j} fi,j意义下的最优性:
    B : f i , k ≤ f i , p B:f_{i,k}\leq f_{i,p} B:fi,kfi,p
    A + T = B A+T=B A+T=B,用还原不等式的方法会发现, T T T恰为四边形不等式,则 B B B得证。
    因此 f i , k ≤ f i , p , f i , k ≥ f i , p f_{i,k}\leq f_{i,p},f_{i,k}\geq f_{i,p} fi,kfi,p,fi,kfi,p,则 f i , k = f i , p f_{i,k}=f_{i,p} fi,k=fi,p,说明 k k k p p p f i , j f_{i,j} fi,j意义上一样优。因此决策单调性得证。

二维四边形不等式优化dp

题解视频

首先考虑考虑设状态:
二叉搜索树的一个子树对应有序序列上一个连续的区间,因为中序遍历要递增。所以一眼区间dp。考虑到贡献与层数有关,我们需要把状态写进层数:
f k , i , j f_{k,i,j} fk,i,j表示目前区域根节点深度为 k k k,区间为 [ i , j ] [i,j] [i,j]的最小贡献。
这个dp很明显是 O ( n 4 ) O(n^4) O(n4)的,但是十秒钟…也可以过。

但是今天说的是四边形不等式优化dp。
我们首先考虑一下如何把状态优化为 O ( n 2 ) O(n^2) O(n2),一般来说牵扯到因为贡献计算而需要增加状态维数的问题,主要有三种计算费用的方法:

  1. 费用提前计算,例如任务安排
  2. 费用即时计算,也就是我们现在这种写法
  3. 费用推迟计算,主要的想法是从 i , j i,j i,j转移的贡献只与 i , j i,j i,j有关,与 k k k无关,那我们可以等到转移的时候从后继计算贡献。
    (不过好像这么简单的技巧应该不需要总结)

因此设 f i , j f_{i,j} fi,j表示区间 [ i , j ] [i,j] [i,j]构成了一颗子树,且假设根深度为 0 0 0时的贡献,则可以写出转移,转移就是枚举选择 k k k为根:
f i , j = min ⁡ k = i j { f i , k − 1 + f k + 1 , j + w k ( i , j ) } f_{i,j}=\overset{j}{\underset{k=i}\min}\{f_{i,k-1}+f_{k+1,j}+w_k(i,j)\} fi,j=k=iminj{fi,k1+fk+1,j+wk(i,j)}

设数字用 a a a表示, s s s表示 a a a的前缀和,则其中贡献函数 w k ( i , j ) = s j − s i − 1 + a k w_k(i,j)=s_j-s_{i-1}+a_k wk(i,j)=sjsi1+ak

时间复杂度 O ( n 3 ) O(n^3) O(n3),足够通过本题了,但是还可以做到更优。

打表打出决策单调性, p i , j − 1 ≤ p i , j ≤ p i + 1 , j p_{i,j-1}\leq p_{i,j}\leq p_{i+1,j} pi,j1pi,jpi+1,j,可以优化为 O ( n 2 ) O(n^2) O(n2)

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=250;
int f[N+5][N+5],p[N+5][N+5];
int a[N+5],s[N+5];
int main() {
	int n;
	for(int i=1;i<=N;i++) p[i][i]=i;
	while(cin>>n) {
		for(int i=1;i<=n;i++) (cin>>a[i]),s[i]=s[i-1]+a[i];
		for(int i=1;i<=n;i++)
			for(int j=i+1;j<=n;j++) f[i][j]=1e9;
		for(int len=2;len<=n;len++)
			for(int i=1,j;(j=i+len-1)<=n;i++) 
//				for(int k=i;k<=j;k++)
				for(int k=p[i][j-1];k<=p[i+1][j];k++)
					if(f[i][j]>f[i][k-1]+f[k+1][j]+s[j]-s[i-1]-a[k])
						f[i][j]=f[i][k-1]+f[k+1][j]+s[j]-s[i-1]-a[k],p[i][j]=k;
		cout<<f[1][n]<<endl;
//		for(int i=1;i<=n;i++,cout<<endl)
//			for(int j=1;j<=n;j++,cout<<' ')
//				cout<<p[i][j];
	}
}

因为贡献函数是一个三元函数,所以不知道怎么样满足四边形不等式,所以主要讲究一个倒推。

证明状态函数满足四边形不等式:
p i , j + 1 = x , p i + 1 , j = y p_{i,j+1}=x,p_{i+1,j}=y pi,j+1=x,pi+1,j=y,则:
{ f i , j ≤ f i , x − 1 + f x + 1 , j + w x ( i , j ) f i + 1 , j + 1 ≤ f i + 1 , y − 1 + f y + 1 , j + 1 + w y ( i + 1 , j + 1 ) f i , x − 1 + f x + 1 , j + 1 + w x ( i , j + 1 ) = f i , j + 1 f i + 1 , y − 1 + g y + 1 , j + w y ( i + 1 , j ) = f i + 1 , j \left\{\begin{matrix} f_{i,j}\leq f_{i,x-1}+f_{x+1,j}+w_x(i,j)\hspace{2.4cm}\\ f_{i+1,j+1}\leq f_{i+1,y-1}+f_{y+1,j+1}+w_y(i+1,j+1)\\ f_{i,x-1}+f_{x+1,j+1}+w_x(i,j+1)=f_{i,j+1}\hspace{1.2cm}\\ f_{i+1,y-1}+g_{y+1,j}+w_y(i+1,j)=f_{i+1,j}\hspace{1.25cm} \end{matrix}\right. fi,jfi,x1+fx+1,j+wx(i,j)fi+1,j+1fi+1,y1+fy+1,j+1+wy(i+1,j+1)fi,x1+fx+1,j+1+wx(i,j+1)=fi,j+1fi+1,y1+gy+1,j+wy(i+1,j)=fi+1,j
加起来:
f i , j + f i + 1 , j + 1 + f x + 1 , j + 1 + g y + 1 , j + w x ( i , j + 1 ) + w y ( i + 1 , j ) ≤ f i , j + 1 + f i + 1 , j + f x + 1 , j + f y + 1 , j + 1 + w x ( i , j ) + w y ( i + 1 , j + 1 ) f_{i,j}+f_{i+1,j+1}+f_{x+1,j+1}+g_{y+1,j}+\textcolor{blue}{w_x(i,j+1)+w_y(i+1,j)}\leq f_{i,j+1}+f_{i+1,j}+f_{x+1,j}+f_{y+1,j+1}+\textcolor{red}{w_x(i,j)+w_y(i+1,j+1)} fi,j+fi+1,j+1+fx+1,j+1+gy+1,j+wx(i,j+1)+wy(i+1,j)fi,j+1+fi+1,j+fx+1,j+fy+1,j+1+wx(i,j)+wy(i+1,j+1)
我们希望把贡献函数约掉,因此希望有这样一个不等式:
w x ( i , j ) + w y ( i + 1 , j + 1 ) ≤ w x ( i , j + 1 ) + w y ( i + 1 , j ) \textcolor{red}{w_x(i,j)+w_y(i+1,j+1)} \leq \textcolor{blue}{w_x(i,j+1)+w_y(i+1,j)} wx(i,j)+wy(i+1,j+1)wx(i,j+1)+wy(i+1,j)
这恰为贡献函数的四边形不等式,带入贡献函数的公式会发现显然成立。
剩下的部分就和石子合并的证明一样了,因此状态函数显然满足四边形不等式。

同理,证明决策单调性的部分也和石子合并一模一样,不写了。

所以我们会发现,同一类转移方程能否四边形不等式优化仅仅和 w w w是否满足四边形不等式相关。

后记

于是皆大欢喜。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值