IOI2000 邮局 加强版 题解

[IOI2000] 邮局 加强版 题解

考虑动态规划,设 f i , j f_{i,j} fi,j 为经过了 i i i 个村庄,正在建第 j j j​ 个邮局的最优距离。

以及 w i , j w_{i,j} wi,j 表示区间 [ i , j ] [i,j] [i,j]​ 内建一个邮局时的距离总和。

a a a 数组表示每个村庄的坐标编号。

朴素版状态转移方程:
f i , j = min ⁡ ( f i , j , f k , j − 1 + w k + 1 , i ) k ∈ [ 0 , i ) f_{i,j}=\min(f_{i,j},f_{k,j-1}+w_{k+1,i}) \\ k\in [0,i) fi,j=min(fi,j,fk,j1+wk+1,i)k[0,i)
根据初一上册数学,可知在区间 [ x , y ] [x,y] [x,y] 中距离所有点的距离之和最短的点为:

2 ∣ x + y 2\mid x+y 2x+y,则点位于 ⌊ x + y 2 ⌋ \lfloor\frac{x+y}{2}\rfloor 2x+y

反之位于 ⌊ x + y + 1 2 ⌋ \lfloor\frac{x+y+1}{2}\rfloor 2x+y+1

注意到,上述状态转移方程,有三个未知数: i , j , k i,j,k i,j,k。可得时间复杂度为 O ( P V 3 ) O(PV^3) O(PV3),肯定过不了。

考虑四边形不等式优化

注意到, w w w​ 函数的状态转移方程为:
w l , r + 1 = w l , r + a r + 1 − a ⌊ l + r + 1 2 ⌋ w_{l,r+1}=w_{l,r}+a_{r+1}-a_{\lfloor\frac{l+r+1}{2}\rfloor} wl,r+1=wl,r+ar+1a2l+r+1
需要简化,过程如下,虽复杂,但重要,可加以理解。
{ w l , r + 1 = w l + r + a r + 1 − a ⌊ l + r + 1 2 ⌋   1 式 w l + 1 , r + 1 = w l + 1 , r + a r + 1 − a ⌊ l + r + 2 2 ⌋   2 式 \begin{cases}w_{l,r+1}=w_{l+r}+a_{r+1}-a_{\lfloor\frac{l+r+1}{2}\rfloor}\ 1式 \\ w_{l+1,r+1}=w_{l+1,r}+a_{r+1}-a_{\lfloor\frac{l+r+2}{2}\rfloor}\ 2式 \end{cases} \\ {wl,r+1=wl+r+ar+1a2l+r+1 1wl+1,r+1=wl+1,r+ar+1a2l+r+2 2
2式 − - 1式,得:
w l + 1 , r + 1 − w l , r + 1 = w l + 1 , r + a r + 1 − a ⌊ l + r + 2 2 ⌋ − w l , r − a r + 1 + a ⌊ l + r + 1 2 ⌋ w l + 1 , r + 1 − w l , r + 1 = w l + 1 , r − w l , r + a ⌊ l + r + 1 2 ⌋ − a ⌊ l + r + 2 2 ⌋ w l + 1 , r + 1 − w l , r + 1 − w l + 1 , r + w l , r = a ⌊ l + r + 1 2 ⌋ − a ⌊ l + r + 2 2 ⌋ w_{l+1,r+1}-w_{l,r+1}=w_{l+1,r}+a_{r+1}-a_{\lfloor\frac{l+r+2}{2}\rfloor} -w_{l,r}-a_{r+1}+a_{\lfloor\frac{l+r+1}{2}\rfloor}\\ w_{l+1,r+1}-w_{l,r+1}=w_{l+1,r}-w_{l,r}+a_{\lfloor\frac{l+r+1}{2}\rfloor} -a_{\lfloor\frac{l+r+2}{2}\rfloor}\\ w_{l+1,r+1}-w_{l,r+1}-w_{l+1,r}+w_{l,r}=a_{\lfloor\frac{l+r+1}{2}\rfloor} -a_{\lfloor\frac{l+r+2}{2}\rfloor} wl+1,r+1wl,r+1=wl+1,r+ar+1a2l+r+2wl,rar+1+a2l+r+1wl+1,r+1wl,r+1=wl+1,rwl,r+a2l+r+1a2l+r+2wl+1,r+1wl,r+1wl+1,r+wl,r=a2l+r+1a2l+r+2
∵ \because 坐标单调上升
∴   a ⌊ l + r + 1 2 ⌋   ≤   a ⌊ l + r + 2 2 ⌋ ∴   a ⌊ l + r + 1 2 ⌋ − a ⌊ l + r + 2 2 ⌋ ≤ 0 w l + 1 , r + 1 − w l , r + 1 − w l + 1 , r + w l , r ≤ 0 w l , r + w l + 1 , r + 1 ≤ w l , r + 1 + w l , r + 1 w l , r + 1 + w l + 1 , r ≥ w l , r + w l + 1 , r + 1 \therefore\ a_{\lfloor\frac{l+r+1}{2}\rfloor}\ \le \ a_{\lfloor\frac{l+r+2}{2}\rfloor}\\ \therefore\ a_{\lfloor\frac{l+r+1}{2}\rfloor}-a_{\lfloor\frac{l+r+2}{2}\rfloor}\le 0\\ w_{l+1,r+1}-w_{l,r+1}-w_{l+1,r}+w_{l,r}\le 0\\ w_{l,r}+w_{l+1,r+1}\le w_{l,r+1}+w_{l,r+1}\\ w_{l,r+1}+w_{l+1,r}\ge w_{l,r}+w_{l+1,r+1}  a2l+r+1  a2l+r+2 a2l+r+1a2l+r+20wl+1,r+1wl,r+1wl+1,r+wl,r0wl,r+wl+1,r+1wl,r+1+wl,r+1wl,r+1+wl+1,rwl,r+wl+1,r+1
通过四边形不等式可知,若 a , b , c , d a,b,c,d a,b,c,d 满足 a ≤ b ≤ c ≤ d a\le b \le c \le d abcd,且 w a , c + w b , d ≤ w a , d + w b , d w_{a,c}+w_{b,d}\le w_{a,d}+w_{b,d} wa,c+wb,dwa,d+wb,d,则称 w w w 为四边形不等式,可以优化时间复杂度。

∵ l ≤ l + 1 ≤ r ≤ r + 1 \because l\le l+1 \le r \le r+1 ll+1rr+1,则可以将 a , b , c , d a,b,c,d a,b,c,d​ 分别带入进去,即:

a = l , b = l + 1 , c = r , d = r + 1 a=l,b=l+1,c=r,d=r+1 a=l,b=l+1,c=r,d=r+1 时:
w l , r + 1 + w l + 1 , r ≥ w l , r + w l + 1 , r + 1 w a , c + w b , d ≥ w a , d + w b , d w_{l,r+1}+w_{l+1,r}\ge w_{l,r}+w_{l+1,r+1}\\ w_{a,c}+w_{b,d}\ge w_{a,d}+w_{b,d} wl,r+1+wl+1,rwl,r+wl+1,r+1wa,c+wb,dwa,d+wb,d
再附上1式 − - 2式的:
w l , r + 1 − w l + 1 , r + 1 = w l , r − a r + 1 − a ⌊ l + r + 1 2 ⌋ − w l + 1 , r + a r + 1 + a ⌊ l + r + 2 2 ⌋ w l , r + 1 − w l + 1 , r + 1 = w l , r − a ⌊ l + r + 1 2 ⌋ − w l + 1 , r + a ⌊ l + r + 2 2 ⌋ w l , r + 1 − w l + 1 , r + 1 − w l , r + w l + 1 , r = a ⌊ l + r + 2 2 ⌋ − a ⌊ l + r + 1 2 ⌋ w_{l,r+1}-w_{l+1,r+1}=w_{l,r}-a_{r+1}-a_{\lfloor\frac{l+r+1}{2}\rfloor} -w_{l+1,r}+a_{r+1}+a_{\lfloor\frac{l+r+2}{2}\rfloor}\\ w_{l,r+1}-w_{l+1,r+1}=w_{l,r}-a_{\lfloor\frac{l+r+1}{2}\rfloor}-w_{l+1,r}+a_{\lfloor\frac{l+r+2}{2}\rfloor}\\ w_{l,r+1}-w_{l+1,r+1}-w_{l,r}+w_{l+1,r}=a_{\lfloor\frac{l+r+2}{2}\rfloor} -a_{\lfloor\frac{l+r+1}{2}\rfloor} wl,r+1wl+1,r+1=wl,rar+1a2l+r+1wl+1,r+ar+1+a2l+r+2wl,r+1wl+1,r+1=wl,ra2l+r+1wl+1,r+a2l+r+2wl,r+1wl+1,r+1wl,r+wl+1,r=a2l+r+2a2l+r+1
∵ \because 坐标单调上升
∴ a ⌊ l + r + 2 2 ⌋ ≥ a ⌊ l + r + 1 2 ⌋ a ⌊ l + r + 2 2 ⌋ − a ⌊ l + r + 1 2 ⌋ ≥ 0 w l , r + 1 + w l + 1 , r − w l + 1 , r + 1 − w l , r ≥ 0 w l , r + 1 + w l + 1 , r ≥ w l + 1 , r + 1 + w l , r \therefore a_{\lfloor\frac{l+r+2}{2}\rfloor}\ge a_{\lfloor\frac{l+r+1}{2}\rfloor}\\ a_{\lfloor\frac{l+r+2}{2}\rfloor}-a_{\lfloor\frac{l+r+1}{2}\rfloor} \ge 0\\ w_{l,r+1}+w_{l+1,r}-w_{l+1,r+1}-w_{l,r}\ge 0 \\ w_{l,r+1}+w_{l+1,r} \ge w_{l+1,r+1}+w_{l,r} a2l+r+2a2l+r+1a2l+r+2a2l+r+10wl,r+1+wl+1,rwl+1,r+1wl,r0wl,r+1+wl+1,rwl+1,r+1+wl,r

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXV=3003,MAXP=305,inf=1e9+5;
int v,p;
int f[MAXV][MAXP];//经过了i个村庄,正在建j个邮局 
int a[MAXV],w[MAXV][MAXV],dp[MAXV][MAXP];
int minn,minid;
signed main(){
	scanf("%d%d",&v,&p);
	for(int i=1;i<=v;i++)
		scanf("%d",&a[i]);
	sort(a+1,a+v+1);
	memset(f,0x3f,sizeof(f));
	f[0][0]=0;
	for(int i=1;i<=v;i++)
		for(int j=i+1;j<=v;j++)
			w[i][j]=w[i][j-1]+a[j]-a[i+j>>1];
	for(int j=1;j<=p;j++)
	{
		dp[v+1][j]=v;
		for(int i=v;i>=1;i--)
		{
			minn=inf;
			for(int k=dp[i][j-1];k<=dp[i+1][j];k++)
			{
				if(f[k][j-1]+w[k+1][i]<minn)
				{
					minn=f[k][j-1]+w[k+1][i];
					minid=k;
				}
			}
			f[i][j]=minn;
			dp[i][j]=minid;
		}
	}			
	printf("%d\n",f[v][p]);
	return 0;
}
  • 36
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值