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

思路:

1. dist[i][j] 表示在村子 i, j 之间选一点建邮局并使得 i,j 之间的所有村子到该邮局的距离之和最小. 选择方法是固定的, 总是选择 i,j 最中间的那个村子, mid = (i+j+1)/2

2. dp[i][j] 表示前 i 个村子建立 j 个邮局后各个村子到邮局的总距离之和的最小值

3. dp[i][j] = dp[k][j-1] + dist[k+1][i], 类似背包, 不过这里有个枚举的过程.

为什么第 k+1 个村庄非得去 (k+1,j) 之间的那个邮局, 这应该是个枚举的过程, 强制 0~j-1 分配 k 个, j~i 分配 1 个, 枚举所有可能性

总结:

1. 四边形不等式: 状态转移方程形如:f[i] = opt{f[j]+w[j , i]}  其中b[i] <= j <= i-1, 同时满足w[i , j] + w[i' , j'] <= w[i , j'] + w[i' , j], 其中 i <= i' <= j' <= j, 则能够使用四边形优化, 减少 k 的枚举量, 加速状态转移

代码:

#include <iostream>
using namespace std;
const int MAXN = 310;
int village[MAXN];
int dist[MAXN][MAXN];
int dp[MAXN][40];
int V, P, S; void preProcess() { for(int i = 1; i <= V; i ++) {
for(int j = i; j <= V; j ++) {
int mid = (i+j+1)>>1;
int sum = 0;
for(int k = i; k <= j; k ++) {
sum += abs(village[mid]-village[k]);
}
dist[i][j] = sum;
}
}
int INF = 0X3f;
memset(dp, INF, sizeof(dp));
dp[0][0] = 0; } // dp[i][j] = min(dp[k][j-1] + dist[k+1][j])
int mainFunc() {
for(int i = 1; i <= V; i ++) {
for(int j = 1; j <= P; j ++) {
for(int k = 0; k < i; k ++) {
dp[i][j] = min(dp[i][j], dp[k][j-1] + dist[k+1][i]);
}
}
} return dp[V][P];
}
int main() {
freopen("E:\\Copy\\ACM\\poj\\1160\\in.txt", "r", stdin);
while(cin>> V >> P) {
for(int i = 1; i <= V; i ++) {
scanf("%d", &village[i]);
}
preProcess(); cout << mainFunc() << endl;
}
return 0;
}

  

POJ 1160 Post Office(区间DP)的更多相关文章

  1. POJ 1160 Post Office(DP+经典预处理)

    题目链接:http://poj.org/problem?id=1160 题目大意:在v个村庄中建立p个邮局,求所有村庄到它最近的邮局的距离和,村庄在一条直线上,邮局建在村庄上. 解题思路:设dp[i] ...

  2. poj 1160 Post Office (间隔DP)

    Post Office Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 15966   Accepted: 8671 Desc ...

  3. POJ - 3280Cheapest Palindrome-经典区间DP

    POJ - 3280 Cheapest Palindrome Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & ...

  4. poj 2955 括号匹配 区间dp

    Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6033   Accepted: 3220 Descript ...

  5. POJ 3280 Cheapest Palindrome (区间DP) 经典

    <题目链接> 题目大意: 一个由小写字母组成的字符串,给出字符的种类,以及字符串的长度,再给出添加每个字符和删除每个字符的代价,问你要使这个字符串变成回文串的最小代价. 解题分析: 一道区 ...

  6. POJ 1141 Brackets Sequence(区间DP, DP打印路径)

    Description We give the following inductive definition of a “regular brackets” sequence: the empty s ...

  7. POJ 2176 Folding(区间DP)

    题意:给你一个字符串,请把字符串压缩的尽量短,并且输出最短的方案. 例如:AAAAA可压缩为5(A), NEERCYESYESYESNEERCYESYESYES可压缩为2(NEERC3(YES)). ...

  8. POJ 2955 Brackets (区间DP,常规)

    题意: 给出一个字符串,其中仅仅含 “ ( ) [ ] ” 这4钟符号,问最长的合法符号序列有多长?(必须合法的配对,不能混搭) 思路: 区间DP的常规问题吧,还是枚举区间[i->j]再枚举其中 ...

  9. POJ - 2955 Brackets (区间DP)

    题目: 给出一个有括号的字符串,问这个字符串中能匹配的最长的子串的长度. 思路: 区间DP,首先枚举区间长度,然后在每一个长度中通过枚举这个区间的分割点来更新这个区间的最优解.还是做的少. 代码: / ...

随机推荐

  1. 使用Scala编写Spark程序求基站下移动用户停留时长TopN

    使用Scala编写Spark程序求基站下移动用户停留时长TopN 1. 需求:根据手机基站日志计算停留时长的TopN 我们的手机之所以能够实现移动通信,是因为在全国各地有许许多多的基站,只要手机一开机 ...

  2. dubbo注册zookeeper保错原因

    我的zookeeper是安装在本地,用的默认端口2181,版本3.4.10.dubbo版本2.5.8.dubbo-demo-provider.xml配置文件修改为:<dubbo:registry ...

  3. Ubuntu 12.04下mysql的安装与配置

    转自:http://blog.csdn.net/ichsonx/article/details/9285935 准备  0. 获取 mysql-5.5.15-linux2.6-i686.tar.gz ...

  4. 分享一个上传图片,图片压缩Unsupported Image Type解决方案

    http://blog.csdn.net/frankcheng5143/article/details/53185201 *************************************** ...

  5. python idea 利用树莓派做家庭报警系统

    1 利用树莓派做家庭报警系统idea 功能如下: 1.程序家侧人不在家(7:00-6:00) 2.树莓派搭配摄像头,对这门进行图像识别,如果变化,门开了,就报警: 3.报警的方式是给我发短信,采信,或 ...

  6. ativemq使用教程

    本文转自http://www.cnblogs.com/zhuxiaojie/p/5564187.html 目录:  一:JMQ的两种消息模式 1.1:点对点的消息模式 1.2:订阅模式 二:点对点的实 ...

  7. ad9 的快捷方式

    TAB:选中元件后,可以显示该元件的属性: PAGEUP:以鼠标所在点为中心,放大视图: PAGEDOWN:以鼠标所在点为中心,缩小视图: HOME:居中,可以从原来光标下的图纸位置,移位到工作区中心 ...

  8. Android——单例模式

    详细的各种模式 http://mobile.51cto.com/android-419145.htm http://wenku.baidu.com/link?url=f3yjQ6YvslvHcWJLb ...

  9. java中静态方法的使用

    JAVA中使用静态方法 编程时我们心里一定要清楚静态方法和类的非静态方法方法的区别: 最根本区别从编译角度来说吧: 1) 静态(static)方法是编译时直接加载加载到内存中(离cpu最近的一块内存区 ...

  10. 字符数组在C++、C#等语言中的操作

    1.C++中操作数组 #include <iostream> using namespace std; int length(char []); void output_frequency ...