前言

昨天XY讲课!讲到这题!还是IOI的题!不过据说00年的时候DP还不流行。

题面

http://poj.org/problem?id=1160

分析

 § 1 中位数

首先我们考虑,若有x1 < x2 < ... < xn,则当∑abs(x - xi)最小时,x为x1 , x2 , ... , xn这n个数的中位数。

证明如下:我们把x1 , x2 , ... , xn看作数轴上n个点,我们先考虑两端,要使abs(x - x1) + abs(x - xn)最小,那么x必定在x1和xn中间,这是个很显然的初中数学题。

好,那么我们就可以置这两个点不管了;剩下的点我们也这样考虑,如此类推,最后要么剩下一个点,要么就是剩下两个点中间的一段区间,答案就显而易见了。证毕。

(在July 1, 2018的AtCoder Contest 100 Task C Linear Approximation就是用这个思路,但是不知道为什么到比赛结束我还是WA,到时候也搞个这题的题解)

§ 2 给定一段村庄怎么放邮局

我们要求每个村庄到邮局距离总和最近,那么给定一段区间里的村庄,我们要找到一个满足要求的村庄建邮局,由上面关于中位数的结论可知,建邮局的村庄就是这段村庄最中间的那个。

§ 3 动态规划

既然我们知道,在一段给定的村庄下放邮局的最小花费,那么很容易想到一个区间DP的思路。

设DP[i][j]表示在编号为1~i的村庄中,建了j个邮局,所需的最小花费。

这时转移方程已经非常明显了:

DP[i][j] = min{ DP[k][j - 1] + cost[k + 1][i] }

其中j - 1 <= k <= i,cost[l][r]表示在l到r的区间里建一个邮局所需花费。

而cost是可以在O(n2)的时间内预处理出来的,那么时限是绝对绰绰有余了。

参考代码

 // POJ1160
// IOI2000
// Post Office
#include <cstdio>
#include <algorithm>
const int MAXV = , MAXP = , INF = 0x3f3f3f3f; int V, P, X[MAXV], DP[MAXV][MAXP], sum[MAXV][MAXV]; int main() {
scanf("%d%d", &V, &P);
int i, j, k, lim;
for (i = ; i <= V; i++) scanf("%d", &X[i]);
for (i = ; i < V; i++)
for (j = i + ; j <= V; j++) sum[i][j] = sum[i][j - ] + X[j] - X[i + j >> ];  // 预处理cost,这里用sum写了
// DP[0][0] = INF;  // 这里注意DP[0][0]=0,但是DP[i][0]=INF,当i > 0时,因为这时候这个状态是没有意义的
for (i = ; i <= V; i++) {
DP[i][] = INF;
lim = std::min(i, P);
for (j = ; j <= lim; j++) {
DP[i][j] = INF;
for (k = j - ; k < i; k++) DP[i][j] = std::min(DP[i][j], DP[k][j - ] + sum[k + ][i]);
}
}
printf("%d\n", DP[V][P]);
return ;
}

总结

如果放在现在,这大概就够个联赛题难度了。但是当年呢DP在算法竞赛中还不常用,所以当年要想到这个思路,是非常不容易了。

附

讲题是zzd大佬还讲了一个很奇怪的方程:

DP[i][j]表示前i个村庄,建了j个邮局,其中第i个村庄一定是邮局的最小花费。

当然这个状态转移也不难写,但是要注意答案不是DP[V][P],而是DP[V + 1][P + 1]。(即加一个假村庄,假村庄上建一个假邮局,这样就会把前面n个村庄的花费也正常纳入了,当然要通过一些手段不计算假村庄的花费)

IOI2000 Post Office (POJ1160)的更多相关文章

  1. [poj1160][IOI2000]Post Office【动态规划】

    传送门 https://vjudge.net/problem/POJ-1160#author=SCU2018 题目描述 在一条水平的公路上建有n个小屋,两个小屋间的距离是它们的横坐标之差的绝对值.保证 ...

  2. 【四边形不等式】POJ1160[IOI2000]-Post Office

    [题目大意] v个村庄p个邮局,邮局在村庄里,给出村庄的位置,求每个村庄到最近邮局距离之和的最小值. [思路] 四边形不等式,虽然我并不会证明:( dp[i][j]表示前i个村庄建j个邮局的最小值,w ...

  3. NOI题库7624 山区建小学(162:Post Office / IOI2000 POST OFFICE [input] )

    7624:山区建小学 Description 政府在某山区修建了一条道路,恰好穿越总共m个村庄的每个村庄一次,没有回路或交叉,任意两个村庄只能通过这条路来往.已知任意两个相邻的村庄之间的距离为di(为 ...

  4. Post Office

    Post Office poj-1160 题目大意:给你在数轴上的n个村庄,建立m个邮局,使得每一个村庄距离它最近的邮局的距离和最小,求距离最小和. 注释:n<=300,m<=min(n, ...

  5. [IOI2000][POJ1160]Post office

    题面在这里 题意 一条路上有\(n\)个村庄,坐标分别为\(x[i]\),你需要在村庄上建设\(m\)个邮局,使得 每个村庄和最近的邮局之间的所有距离总和最小,求这个最小值. 数据范围 \(1\le ...

  6. POJ1160 Post Office[序列DP]

    Post Office Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18680   Accepted: 10075 Des ...

  7. 【poj1160】 Post Office

    http://poj.org/problem?id=1160 (题目链接) 题意 按照递增顺序给出一条直线上坐标互不相同的n个村庄,要求从中选择p个村庄建立邮局,每个村庄使用离它最近的那个邮局,使得所 ...

  8. POJ1160 Post Office (四边形不等式优化DP)

    There is a straight highway with villages alongside the highway. The highway is represented as an in ...

  9. 题解【POJ1160】Post Office

    [POJ1160]Post Office Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22362 Accepted: 1208 ...

随机推荐

  1. ElasticSearch搜索引擎在JavaWeb项目中的应用

    近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...

  2. 七 Appium常用方法介绍

    文本转自:http://www.cnblogs.com/sundalian/p/5629609.html 由于appium是扩展了Webdriver协议,所以可以使用webdriver提供的方法,比如 ...

  3. Git与远程仓库关联以及关联错误解决方法

    假设你github的用户名是  helloworld  ,你在上面创建了一个 名为 hello 的 repository. 一. 与本地仓库进行关联 1.1用原生ssh进行关联,速度快: git re ...

  4. Python递归算法入门

    递归是一种算法,它在编程里面有着广泛的应用: 1. 递归必须满足哪两个基本条件? 一.函数调用自身 二.设置了正确的返回条件 2. 思考一下,按照递归的特性,在编程中有没有不得不使用递归的情况? 答: ...

  5. .NET中发送邮件的实现

    .NET中发送邮件 注意: 1.引用下列命名空间: using System.Net; using System.Net.Mail; 2.确保你使用的发送邮件的邮箱开启了stamp服务等. /// & ...

  6. HADOOP/HDFS Essay

    HDFS架构 the core of HADOOP/distributed systems is storeage(HDFS) and resource manager(YARN) for compu ...

  7. 从SDN鼻祖Nicira到VMware NSX 网络虚拟化平台的简单探讨

    以前的大二层技术,一般是在物理网络底层使用IS-IS路由技术,再在此基础之上,实现数据中心网络的二层扩展,如公有的Trill.SPB技术和Cisco私有的OTV.Fabricpath技术:前沿一些的网 ...

  8. 索引值迭代-enumerate

    你想在迭代一个序列的同时跟踪正在被处理的元素索引?内置的enumerate() 函数可以很好的解决这个问题: list_c = ['a', 'b', 'c'] for i, c in enumerat ...

  9. Hybrid APP基础篇(五)->JSBridge实现示例

    说明 JSBridge实现示例 目录 前言 参考来源 楔子 JS实现部分 说明 实现 Android实现部分 说明 JSBridge类 实现 Callback类 实现 Webview容器关键代码 实现 ...

  10. 2018-8-29安装Jitamin过程实录

    2018-8-29安装Jitamin过程实录 新建 模板 小书匠 欢迎走进zozo的学习之旅. 简介 安装 nginx + php + mysql 安装composer 安装Jitamin 简介 在考 ...