Description

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.

Output

The first line contains one integer S, which is the sum of all distances between each village and its nearest post office.

Sample Input

10 5

1 2 3 6 7 9 11 22 44 50

Sample Output

9

Source

IOI 2000

Solution

简化版题意:有N个村庄,每个村庄均有一个唯一的坐标,选择P个村庄建邮局,问怎么选择,才能使每个村庄到其最近邮局的距离和最小,输出这个最小值。

本题是一道区间DP题,比较复杂。

当我们在v个村庄中只建一个邮局,可以推导出,只有邮局位于中间位置,距离和才最小。

有一个特殊情况是,当村庄数为偶数,中间位置有两个村庄,经过计算,两个村庄的距离和相等,所以两个位置均可。

可以联想到,N个村庄建P个邮局,相当于每个邮局均有一个作用范围,该邮局位于其作用范围的中间位置,就是要找到一个k,使前k个村庄建P - 1个邮局,最后几个村庄建一个邮局的方案满足题意。

那么,我们设:

dp[i][j]:前i个村庄建j个邮局的最小距离和

b[i][j]:第i个村庄到第j个村庄之间建1个邮局的最小距离和

因此,状态转移方程就是:

dp[i][j] = min(dp[i][j],dp[k][j - 1] + b[k + 1][j])

还有一点,计算b[i][j]时,b[i][j - 1]已经计算出来,而且可以推导出无论j为奇数还是偶数,b[i][j]均可以写成b[i][j - 1] + j距离i、j中点的距离。

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>//头文件 using namespace std;//使用标准名字空间 inline int gi()//快速读入
{
int f = 1, x = 0;
char c = getchar(); while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
} while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
} return f * x;
} int n, m, a[305], sum, b[305][305], dp[305][305];//m即为题中的p,sum为最终答案,b数组和dp数组的含义同Solution int main()
{
n = gi(), m = gi(); for (int i = 1; i <= n; i++)
{
a[i] = gi();
}
//输入
memset(dp, 0x3f3f3f3f, sizeof(dp));//初始化dp数组为最大值 for (int i = 1; i < n; i++)
{
for (int j = i + 1; j <= n; j++)
{
b[i][j] = b[i][j - 1] + a[j] - a[(i + j) >> 1];//b数组的初始化
}
} for (int i = 1; i <= n; i++)
{
dp[i][1] = b[1][i];//只建一个邮局的预处理
} for (int i = 2; i <= m; i++)//要建i个邮局
{
for (int j = i; j <= n; j++)//1~j号村庄建i个邮局
{
for (int k = i - 1; k <= j - 1; k++)//1~k号村庄建i- 1个邮局
{
dp[j][i] = min(dp[j][i], dp[k][i - 1] + b[k + 1][j]);//DP主过程
}
}
} sum = dp[n][m];//答案即为dp[n][m],就是在1~n号村庄中建m个邮局 printf("%d", sum);//输出最终答案 return 0;//结束
}

最新文章

  1. 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
  2. java Ajax的应用
  3. 阿里云Centos 6.3 64位 安全加固版 升级 Php 中的 Curl 7.19 到 7.35
  4. Grid画边框
  5. the computer spends over 96% of its time waiting for I/O devices to finish transferring data
  6. hdu 1033 (bit masking, utilization of switch, &#39;\0&#39; as end of c string) 分类: hdoj 2015-06-15 21:47 37人阅读 评论(0) 收藏
  7. spring security 11种过滤器介绍
  8. JavaScript_object基础
  9. Intellij Idea 创建Web项目入门(一)转
  10. Redis监控数据分布工具Redis-audit 使用总结
  11. ZendStudio9之SVN项目代码提示丢失解决
  12. SQL Server函数​---Union与Union All的区别
  13. github--hello,world(参考官网)
  14. 使用xorm工具,根据数据库自动生成 go 代码
  15. BigDecimal工具类处理精度计算
  16. 【剑指offer】扑克牌的顺子
  17. Python【每日一问】08
  18. Hadoop完全分布式安装
  19. hibernate 中文文档
  20. laravel的firstOrCreate的作用:先查找表,如果有就输出数据,如果没有就插入数据

热门文章

  1. Local changes were not restore
  2. Java第五节课总结
  3. 替换 MyEclipse 中已有的项目
  4. RHEL 8 安装 Oracle 19c 注意问题
  5. PGET,一个简单、易用的并行获取数据框架
  6. Redis是什么? —— Redis实战经验
  7. SpringBoot之spring.factories
  8. pytest-测试用例teardown和setup
  9. 数据库SQL练习(一):数据查询
  10. 机器学习作业(二)逻辑回归——Matlab实现