[IOI2000]邮局 题解
简要题意
线段上有 \(V\) 个村庄,现在要建 \(P\) 个邮局,使每个村庄到最近的邮局的距离之和最小。
50分做法
设\(dp[i][j]\) 表示第一个村庄到第 \(i\) 个村庄,建了 \(j\) 个邮局的最小距离,不难得出状态转移方程:
\(dp[i][j]=min(dp[k][j-1]+w[k+1][i])\),
其中 \(w[i][j]\) 表示在第 \(i\) 和 \(j\) 个村庄之间建一个邮局的最短总距离。
根据初中知识不难求得,邮局建在第 \(i\) 到 \(j\) 个村庄的中位数的位置上(奇数个村庄)或第 \(i\) 到 \(j\) 个村庄的两个中位数之间(偶数个村庄),则总距离最短,因此我们可以递推求出 \(w[i][j]\),\(w[i][j]=\begin{cases}
& 0\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ } i=j \\
& w[i][j-1]+v[j]-v[(i+j)/2] \text{ }\text{ }\text{ }\text{ }\text{ }i<j\end{cases} \text{ }\) ,其中 \(v[i]\) 表示第 \(i\) 个村庄的位置。
证明:
当第 \(i\) 到 \(j\) 个村庄为奇数个时,第 \(i\) 到 \(j-1\) 个村庄为偶数个,第 \(i\) 到 \(j-1\) 个村庄的中位数为第 \(\left \lfloor \frac{(i+j-1)}{2} \right \rfloor\) 个村庄和第 \(\left \lceil \frac{(i+j-1)}{2} \right \rceil\) 个村庄,第 \(i\) 到 \(j\) 个村庄的中位数为第 \(\frac{(i+j)}{2}\) 即 \(\left \lceil \frac{(i+j-1)}{2} \right \rceil\) 个村庄;
当第 \(i\) 到 \(j\) 个村庄为偶数个时,第 \(i\) 到 \(j-1\) 个村庄为奇数个,第 \(i\) 到 \(j-1\) 个村庄的中位数为第 \(\frac{(i+j-1)}{2}\) 个村庄,第 \(i\) 到 \(j\) 个村庄的中位数为第 \(\left \lfloor \frac{(i+j)}{2} \right \rfloor\) 即 \(\frac{(i+j-1)}{2}\) 个村庄和第 \(\left \lceil \frac{(i+j)}{2} \right \rceil\) 个村庄;
此时第 \(i\) 到 \(j-1\) 个村庄到邮局的距离之和不变,第 \(j\) 个村庄到邮局的距离即第 \(j\) 个村庄到第 \(i\) 到 \(j\) 个村庄的中位数的距离,即第 \(j\) 个村庄的位置减去第 \(i\) 到 \(j\) 个村庄的中位数的位置。
预处理 \(w[i][j]\) 之后,我们可以三层循环分别枚举 \(i,j,k\),时间复杂度为 \(O(V^{2}P)\) ,无法通过大数据。
满分做法
这是一道DP数组二维的区间DP,并且状态转移方程为 \(dp[i][j]=dp[i][k]+dp[k+1][j]+w[i][j]\) 的形式,因此考虑四边形不等式优化。
四边形不等式
定义:
如果对于任意的 \(A\leq B\leq C\leq D\),均满足 \(w[A][C]+w[B][D]\leq w[A][D]+w[B][C]\),则称 \(w\) 满足四边形不等式。
证明:
在这一题中,根据 \(w[i][j]\) 的递推式,可得
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }w[i][j+1]-w[i][j]=v[j+1]-v[(i+j+1)/2]\),
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }w[i+1][j+1]-w[i+1][j]=v[j+1]-v[(i+j+2)/2]\),
两者相减,得
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }w[i][j+1]-w[i][j]-(w[i+1][j+1]-w[i+1][j])\)
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }=v[j+1]-v[(i+j+1)/2]-(v[j+1]-v[(i+j+2)/2])\)
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }=v[j+1]-v[(i+j+1)/2]-v[j+1]+v[(i+j+2)/2]\)
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }=v[(i+j+2)/2]-v[(i+j+1)/2]\geq 0\),
则
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }w[i][j+1]-w[i][j]-(w[i+1][j+1]-w[i+1][j])\geq 0\),
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }w[i][j+1]-w[i][j]-w[i+1][j+1]+w[i+1][j]\geq 0\),
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }w[i][j]+w[i+1][j+1]\leq w[i][j+1]+w[i+1][j]\),
\(w\) 满足四边形不等式,则 \(dp\) 同样满足四边形不等式,设 \(s[i][j]\) 为 \(dp[i][j]\) 的最优决策点 \(k\),可得\(s[i][j]\)单调,即\(s[i][j]\leq s[i][j+1]\leq s[i+1][j+1]\),\(s[i][j-1]\leq s[i][j]\leq s[i+1][j]\)(这一点的证明后面会提到),每次让 \(k\) 在 \(s[i][j-1]\) 到 \(s[i+1][j]\) 的范围内枚举,就将原本 \(O(V^{2}P)\) 的DP变为 \(O(VP)\) 的了,可以AC,注意此时 \(i\) 需要倒着枚举,因为需要用到 \(s[i+1][j]\)。
对 \(s[i][j-1]\leq s[i][j]\leq s[i+1][j]\) 的证明
假设状态规划方程是 \(dp[i][j]=dp[i][k]+dp[k+1][j]+w[i][j]\) 的形式,设 \(y\) 为使 \(dp[i][j-1]\) 最小的 \(k\),即 \(s[i][j-1]\),令 \(x<y\),有 \(x+1\leq y+1\leq j-1<j\),根据四边形不等式,得
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }dp[x+1][j-1]+dp[y+1][j]<=dp[y+1][j-1]+dp[x+1][j]\),
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }dp[i][x]+dp[x+1][j-1]+w[i][j-1]+dp[i][y]+dp[y+1][j]+w[i][j]
<=\)
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }
dp[i][x]+dp[x+1][j]+w[i][j]+dp[i][y]+dp[y+1][j-1]+w[i][j-1]\),
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }dp[i][j-1](k=x)+dp[i][j](k=y)<=dp[i][j](k=x)+dp[i][j-1](k=y)\),
\(\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }\text{ }dp[i][j-1](k=x)-dp[i][j-1](k=y)<=dp[i][j](k=x)-dp[i][j](k=y)\),
不等式左右两边显然都大于0(\(y\) 是最优决策点,\(dp[i][j]\) 的值最小),所以 \(dp[i][j]\) 的最优决策点一定不是任意一个 \(x\),即 \(s[i][j]\geq s[i][j-1]\)(即 \(y\)),同理可证\(s[i][j]\leq s[i+1][j]\)。
细节
- 在预处理前需要对 \(v\) 进行排序,保证 \(v[i]\) 的单调(递增)性,否则 \(w[i][j]\) 就不满足四边形不等式,也就无法使用四边形不等式优化了,然而这题数据较水,给出的 \(v[i]\) 本身就是单调递增的,无需排序(别问我怎么知道的)。
- DP数组要初始化成INF,且\(dp[i][1]=w[1][i]\),DP时 \(j\) 从 \(2\) 开始枚举,否则会使用 \(s[i][0]\) 和 \(dp[k][0]\)。
- 注意 \(s\) 的边界值:\(s[i][1]=1\)(只建1个邮局时最佳划分点只能是第一个村庄),\(s[v+1][i]=v-1\)(倒序枚举 \(dp[i][j]\) 中的 \(i\),\(v-1\) 即最佳决策点 \(k\) 范围的初始值)。
代码
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int v,p,a[3005],w[3005][3005],f[3005][3005],s[3005][3005],i,j,k;
int main()
{
ios::sync_with_stdio(false);
cin>>v>>p;
for(i=1;i<=v;++i)cin>>a[i];//输入
//这里本应有sort,但是本题数据过水,a[i]本来就单调递增
for(i=1;i<v;++i)
for(j=i+1;j<=v;++j)
w[i][j]=w[i][j-1]+a[j]-a[i+j>>1];//预处理w[i][j]
//下面几行都是预处理
for(i=1;i<=v;++i)
for(j=1;j<=p;++j)f[i][j]=INF;
for(i=1;i<=v;++i)f[i][1]=w[1][i],s[i][1]=1;
for(i=1;i<=p;++i)s[v+1][i]=v-1;
//上面几行都是预处理
for(i=2;i<=p;++i)//枚举邮局数
for(j=v;j>=i;j--)//倒序枚举村庄
for(k=s[j][i-1];k<=s[j+1][i];++k)//四边形不等式优化
if(f[k][i-1]+w[k+1][j]<f[j][i])
f[j][i]=f[k][i-1]+w[k+1][j],s[j][i]=k;//记得更新最优决策点
cout<<f[v][p]<<endl;
return 0;
}
[IOI2000]邮局 题解的更多相关文章
- BZOJXXXX: [IOI2000]邮局——四边形不等式优化初探
貌似$BZOJ$上并没有这个题... 是嫌这个题水了么... 还是要氪金权限号??? 这里附上洛谷的题面:洛谷P4767 [IOI2000]邮局 题目描述 高速公路旁边有一些村庄.高速公路表示为整数轴 ...
- COGS 1507. [IOI2000]邮局
1507. [IOI2000]邮局 ★☆ 输入文件:postoffice.in 输出文件:postoffice.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] ...
- 题解——洛谷P4767 [IOI2000]邮局(区间DP)
这题是一道区间DP 思维难度主要集中在如何预处理距离上 由生活经验得,邮局放在中间显然最优 所以我们可以递推求出\( w[i][j] \)表示i,j之间放一个邮局得距离 然后设出状态转移方程 设\( ...
- P4767 [IOI2000]邮局 - 平行四边形不等式优化DP
There is a straight highway with villages alongside the highway. The highway is represented as an in ...
- [IOI2000] 邮局
## 非常神仙的 wqs 二分优化dp,又学了一招. 首先我们需要先想到一个人类智慧版的前缀和优化. # part 1:violence 然鹅在前缀和优化之前我们先考虑暴力做法:我们可以枚举 i . ...
- [LUOGU] P4767 [IOI2000]邮局
https://www.luogu.org/problemnew/show/P4767 四边形不等式好题! 可以设f[i][j]表示前i个村庄,建了j个邮局的最小代价. 转移:f[i][j]=min{ ...
- luogu_P4767 [IOI2000]邮局
传送门 Description 高速公路旁边有一些村庄.高速公路表示为整数轴,每个村庄的位置用单个整数坐标标识.没有两个在同样地方的村庄.两个位置之间的距离是其整数坐标差的绝对值. 邮局将建在一些,但 ...
- 【LSGDOJ 1408】邮局
题目描述 一些村庄被建在一条笔直的高边公路边上.我们用一条坐标轴来描述这条高边公路,每一个村庄的坐标都是整数.没有两个村庄坐标相同.两个村庄问的距离,定义为它们坐标值差的绝对值. 我们需要在一些村庄建 ...
- 我的刷题单(8/37)(dalao珂来享受切题的快感
P2324 [SCOI2005]骑士精神 CF724B Batch Sort CF460C Present CF482A Diverse Permutation CF425A Sereja and S ...
- 决策单调性&wqs二分
其实是一个还算 trivial 的知识点吧--早在 2019 年我就接触过了,然鹅当时由于没认真学并没有把自己学懂,故今复学之( 1. 决策单调性 引入:在求解 DP 问题的过程中我们常常遇到这样的问 ...
随机推荐
- TypeScript项目开发运行(即时编译、运行,所见所得)
1.项目*.ts自动编译 $ tsc . --watch 2.项目本地web服务运行 $ npm install --save-dev webpack-dev-server npm install - ...
- 【Azure 应用服务】Azure Powershell Function 出错 The term 'Connect-AzAccount' is not recognized
问题描述 在Azure Function中,执行Powershell的Function脚本时,先后出现 1:[Error] ERROR: The term 'Connect-AzAccount' is ...
- C++异常的基本概念与用法
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try{}内写可能会抛出异常的代码.catch(类型){处理} 写异常类型和异常处理 抛出 ...
- 三: MySQL的数据目录
# MySQL的数据目录 1. MySQL8的主要目录结构 1.1 数据库文件的存放路径 MySQL数据库文件的存放路径:/var/lib/mysql/ MySQL服务器程序在启动时会到文件系统的某个 ...
- 1. Canal入门
1. Canal简介 官方文档: https://github.com/alibaba/canal/wiki/简介 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求.早期 ...
- 8、mysql的内存管理及优化
内存优化原则 1) 将尽量多的内存分配给MySQL做缓存,但要给操作系统和其他程序预留足够内存. 2) MyISAM 存储引擎的数据文件读取依赖于操作系统自身的IO缓存,因此,如果有MyISAM表,就 ...
- Python基础之程序与用户交互
[一]Python基础之程序与用户交互 [一]程序如何与用户交互 用户通过input命令在窗口内与输入就可以让用户和窗口进行交流 input接受的所有数据类型都是 str 类型 username = ...
- MacOS安装gRPC C++
从源码安装gRPC C++ 环境准备 $ [sudo] xcode-select --install $ brew install autoconf automake libtool shtool $ ...
- springboot发送邮件的几种方式
准备工作(以QQ邮箱为例) SMTP 协议全称为 Simple Mail Transfer Protocol,译作简单邮件传输协议,它定义了邮件客户端软件与 SMTP 服务器之间,以及 SMTP 服务 ...
- 解决Windows下json.hpp中文乱码问题
文中使用的是 json 库,整个库的代码由一个单独的头文件json.hpp组成,用普通的C++11编写的.它没有库,没有子项目,没有依赖关系,没有复杂的构建系统,使用起来很方便. 先引用头文件和命名空 ...