There is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each village is identified with a single integer coordinate. There are no two villages in the same position. The distance between two positions is the absolute value of the difference of their integer coordinates. 

Post offices will be built in some, but not necessarily all of the villages. A village and the post office in it have the same position. For building the post offices, their positions should be chosen so that the total sum of all distances between each village and its nearest post office is minimum. 

You are to write a program which, given the positions of the villages and the number of post offices, computes the least possible sum of all distances between each village and its nearest post office.

在高速公路旁边有一条村庄的直道。高速公路表示为整数轴,并且每个村庄的位置用单个整数坐标标识。同一地点没有两个村庄。两个位置之间的距离是它们整数坐标差的绝对值。 

        邮局将建在一些但不一定是所有村庄。一个村庄和其中的邮局具有相同的位置。为了建造邮局,应选择其位置,以便每个村庄与其最近的邮局之间的所有距离的总和最小。 

        你要写一个程序,考虑到村庄的位置和邮局的数量,计算每个村庄和最近的邮局之间所有距离的最小可能总和。

Input

Your program is to read from standard input. The first line contains two integers: the first is the number of villages V, 1 <= V <= 300, and the second is the number of post offices P, 1 <= P <= 30, P <= V. The second line contains V integers in increasing order. These V integers are the positions of the villages. For each position X it holds that 1 <= X <= 10000.

此程序是从标准输入读取。第一行包含两个整数:第一行是村庄的数量V,1 <= V <= 300,第二行是邮局的数量P,1 <= P <= 30,P <= V. 第二行按升序包含V个整数。这V个整数是村庄的位置。对于每个位置X,保证 1 <= X <= 10000。

Output

The first line contains one integer S, which is the sum of all distances between each village and its nearest post office.第一行包含一个整数S,它是每个村庄与其最近的邮局之间所有距离的总和。

方法

这道题是一道DP题,由于DP题有一个常见的性质,即 f [ ][ ] 数组中存的子解都具有可输出的共同点,所以这种DP题的状态转移方程都是很好推断的。这道题的 f [ i ] [ j ] 表示前 i 个村庄建 j 个邮局的解,状态转移方程是

由于此复杂度是O(),但是数据量很小,所以用朴素DP是可以做出来的。

但是,为了提升自我增长知识,我决定优化一下,把复杂度降为O(),具体是用一种叫“平行四边形不等式优化DP”的方式,把 K 的枚举平摊成一次O(n)。

判断是否能用此法,主要靠

1) 暴力打表找规律

2) 凭直觉

平行四边形优化主要有一个特点,每一个 f [ i ][ j ] 最后的 k 值都大于 f [ i ][ j - 1 ] 的 k ,且小于 f [ i + 1 ][ j ] 的 k 。意思是,状态转移方程可以优化:

主要是因为 w [][] 具有平行四边形不等式的性质,即对于 a < b < c < d ,

w [ a ] [ c ] + w [ b ] [ d ] <  w [ a ] [ d ] +  w [ b ] [ c ] 。

这可以算是最难的一种方法,因为坑很多,很难AC,但是一般只要样例过了,就离成功不远了。

详见大神题解:https://blog.csdn.net/NOIAu/article/details/72514812

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int read() {
int f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
return x * f;
}
int n,m,i,j,k,o;
int pos[3005],f[3005][305],w[3005][3005],sum1[3005],sum2[3005],s[3005][3005];
int main() {
n = read();m = read();
for(i = 1;i <= n;i ++) {
pos[i] = read();
}
for(i = 1;i <= n;i ++) {
sum1[i] = sum1[i - 1] + pos[i] - pos[1];
}
for(i = n;i > 0;i --) {
sum2[i] = sum2[i + 1] + pos[n] - pos[i];
}
for(i = 1;i <= n;i ++) {
for(j = i;j <= n;j ++) {
if(i == j) w[i][j] = 0;
else {
int k = (i + j) / 2;
w[i][j] = sum1[j] - sum1[k] - (j - k) * (pos[k] - pos[1]) + sum2[i] - sum2[k] - (k - i) * (pos[n] - pos[k]);
}
}
}
memset(f,0x3f,sizeof(f));
for(i = 1;i <= n;i ++) {
f[i][1] = w[1][i];
}
f[0][0] = f[1][1] = 0;
for(i = 1;i <= n;i ++) {
for(j = min(i,m);j > 0;j --) {
if(!s[i - 1][j]) s[i - 1][j] = min(i - 1,j - 1);
if(!s[i][j + 1]) s[i][j + 1] = i - 1;
for(k = s[i - 1][j];k <= s[i][j + 1];k ++) {
if(f[k][j - 1] + w[k + 1][i] < f[i][j]) {
f[i][j] = f[k][j - 1] + w[k + 1][i];
s[i][j] = k;
}
}
}
}
printf("%d",f[n][m]);
return 0;
}

最新文章

  1. Spring之旅(2)
  2. dll导入导出宏定义,出现“不允许 dllimport 函数 的定义”的问题分析
  3. jq 模板
  4. 在CentOS 6.6下安装与配置mysql
  5. JavaWeb学习记录(八)——servlet获取配置信息
  6. jQuery 效果 - slideDown() 方法[菜单导航栏常用]
  7. 《Dive into Python》Chapter 2 and Chapter 3 笔记
  8. hiveserver2 后台运行
  9. ACM ICPC Asia Regional 2011 Kuala Lumpur C题
  10. 【4】项目结构+基本的Tornado服务
  11. Coroutine,你究竟干了什么?
  12. Quartz_理解3
  13. CSS样式----浮动(图文详解)
  14. 【JAVA零基础入门系列】Day12 Java类的简单应用
  15. 4.熟悉App Inventor 2编程界面
  16. ccse(CountDownLatch,CycliBarrier,Semaplore,Exchanger)
  17. wordpress中安装插件需要ftp服务
  18. angular,vue,react的基本语法—动态属性、事件绑定、ref,angular组件创建方式
  19. 关于IOS下click事件委托失效的解决方案
  20. codeforces146A

热门文章

  1. 分享自己平时使用的socket多客户端通信的代码技术点和软件使用
  2. 安装gitlab客户端
  3. rhel7修改网卡名
  4. 一种让运行在CentOS下的.NET CORE的Web项目简单方便易部署的自动更新方案
  5. Lua5.4源码剖析:二. 详解String数据结构及操作算法
  6. 爬虫(9) - Scrapy框架(1) | Scrapy 异步网络爬虫框架
  7. 面试突击62:group by 有哪些注意事项?
  8. Training a classifier
  9. 模电Multisim仿真Rb变化对Q点和电压放大倍数的影响
  10. URL网络编程