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. servlet的编码原理

    编码问题: 在介绍编码问题前,先介绍一下java平台(JVM)上的编码转化情况.首先要说明的一点,在JVM中,即java平台上,运行的程序一定都是Unicode编码方式的.对于代码中的字符串常量,根据 ...

  2. js字母大小写字母转换

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD ...

  3. 拷贝内容到eclipse中导致JSP的auto-completion不工作

    刚才在编辑JSP文件,有一些东西我懒得敲了,就把一些代码里面拷贝到eclipse的editor中,结果你猜怎么,拷贝进去以后,jsp的auto-completion居然不工作了!(即<%%> ...

  4. ip_conntrack table full dropping packet解决方案

    在一台繁忙的服务器上,建议关闭ip_conntrack模块的加载: 当我们开启iptables后,会有这么个现象发生,丢包.ping的话会断断续续的丢包,ifconfig 会看到网卡dropped:X ...

  5. Android开发日记(三)

    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentV ...

  6. IOS 使用XIB 自定义View

    一般自定义View       代码方式 有 在初始化的时候添加 子Views - (id)initWithFrame:(CGRect)frame { self = [super initWithFr ...

  7. spark sql 入门

    package cn.my.sparksql import cn.my.sparkStream.LogLevel import org.apache.spark.{SparkConf, SparkCo ...

  8. Apache HttpComponents 多线程处理HTTP请求

    /* * ==================================================================== * * Licensed to the Apache ...

  9. 消息队列(RabbitMQ、zorneQ、metaQ、activeMQ)

    术语: AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计. JMS, ...

  10. DataGridView使用技巧十一:DataGridView用户输入时,单元格输入值的设定

    通过DataGridView.CellParsing事件可以设定用户输入的值.下面的示例:当输入英文文本内容的时候,立即被改变为大写.DataGridView.CellParsing在离开编辑的单元格 ...