博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1160:Post Office 邮局经典DP
阅读量:7090 次
发布时间:2019-06-28

本文共 3246 字,大约阅读时间需要 10 分钟。

Post Office
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 17168   Accepted: 9270

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 51 2 3 6 7 9 11 22 44 50

Sample Output

9
题意是给了V个村庄,要在这些村庄中选出P个建立邮局,要求的是建成了P个邮局之后,所有村庄到邮局的距离最短。求最短距离。

冲着邮局的经典DP做的。暴力的话肯定TLE,所以只能往DP上想。

然后就从小了开始想,如果是从a点到b点(中间b-a+1个村庄)建立1个邮局的话,那肯定是要建在中间的村庄上没跑了。1和3的话,要建在2。1和4的话建在2或者3都行因为距离是一样的。

然后这个规律自己做得时候也发现了:

用sum[i][j]表示村庄i到村庄j建立一个邮局的距离。那么推导有sum[i][j]=sum[i][j-1]+value[j]-value[(i+j)/2]

你看,sum[1][4](建在2或者3)=(value[4]-value[3])+(value[3]-value[2])+(value[3]-value[1])

                                              =value[4]+value[3]-value[2]-value[1]

而sum[1][5](建在3)=(value[5]-value[3])+(value[4]-value[3])+(value[3]-value[2])+(value[3]-value[1])

                              =value[5]+value[4]-value[2]-value[1]

通过这样可以发现这个规律:sum[i][j]=sum[i][j-1]+value[j]-value[(i+j)/2]

所以这样就把建在1到V个村庄的P个邮局这个问题拆开了,知道了某部分建立一个邮局的最优解,之后就是dp推导。

用dp[i][j]表示从1到j个村庄建立第i个邮局时的最优解,则有dp[i][j]=min(dp[i][j],dp[i-1][k-1]+sum[k][j]);

上面的推导公式表示将1到j个村庄建立i个邮局分成两部分,一部分是1到k-1个村庄建立i-1个邮局的最优解,另一部分是k到j建立一个邮局的最优解,不断从1到j枚举k的取值,选出最小的值即是最优解。

做这道题有一个问题当时想不出来是起始值不知道怎么确定,现在总结的话,真是猪头啊光速小子。初始值不就是dp[1][i]=sum[1][i]啊。当时居然完全没思路想不出来。。。

代码:

#include 
#include
#include
#include
#include
#include
#pragma warning(disable:4996)using namespace std;int V,P;int value[305];int sum[305][305];int dp[35][305];int main(){ int i,j,k; memset(sum,0,sizeof(sum)); for(i=0;i<=30;i++) { for(j=0;i<=300;j++) { dp[i][j]=10000; } } cin>>V>>P; value[0]=0; for(i=1;i<=V;i++) { cin>>value[i]; } sum[1][2]=value[2]-value[1]; for(i=1;i<=V;i++) { for(j=i+1;j<=V;j++) { sum[i][j]=sum[i][j-1]+value[j]-value[(i+j)/2]; } } for(i=1;i<=V;i++)//!!!!起始值 { dp[1][i]=sum[1][i]; } for(i=2;i<=P;i++) { for(j=i;j<=V;j++) { for(k=1;k<=j;k++) { dp[i][j]=min(dp[i][j],dp[i-1][k-1]+sum[k][j]); } } } cout<
<

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/lightspeedsmallson/p/4785789.html

你可能感兴趣的文章
关系型数据库之MySQL
查看>>
算法笔记-二叉树
查看>>
编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,并输出计算结果总是100的所有可能性。...
查看>>
Java异常处理课后作业
查看>>
hrtf 旋转音效matlab实现
查看>>
__attribute__
查看>>
【Android每日一讲】2012.11.06 Android变脸 - 主题(Theme)实现
查看>>
redis 系列12 哈希对象
查看>>
QTP使用心得
查看>>
js/jq ajax+数组。个人整理
查看>>
mac 下批量转换文件类型
查看>>
何为DOM对象
查看>>
linux的yum仓库配置
查看>>
XSUPERSMS COME ON
查看>>
[JS2] JS是弱类型
查看>>
企业搜索引擎开发之连接器connector(二十四)
查看>>
数学图形(1.9)悬链线
查看>>
有上下界的网络流问题
查看>>
AspectJ获取方法注解的信息
查看>>
HDU 4902 Nice boat(线段树)
查看>>