题目链接:http://poj.org/problem?id=1160

题目大意:在v个村庄中建立p个邮局,求所有村庄到它最近的邮局的距离和,村庄在一条直线上,邮局建在村庄上。

解题思路:设dp[i][j]表示到第i个村庄为止建立j个邮局的最小距离和,dis[i][j]表示i~j之间建一个邮局的最小距离和,我们很容易得出状态转移方程:dp[i][j]=min{dp[k][j]+dis[k+1][i]}(k<i)。

     主要是dis[i][j]的预处理很巧妙,从别人的博客上看的“将邮局建在i~j中间即(i+j)/2的位置,如果i+j不能被整除建在左边和右边结果一样”。于是dis[i][j]=dis[i][j-1]+pos[j]-pos[(i+j)/2]。

代码:

 #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1e3+; int dp[N][],pos[N],dis[N][N];//dis[i][j]表示在i~j之间建一个邮局的最小距离和 int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
memset(dp,0x3f,sizeof(dp));
for(int i=;i<=n;i++){
scanf("%d",&pos[i]);
}
//预处理dis[i][j]
for(int i=;i<=n;i++){
dis[i][i]=;
for(int j=i+;j<=n;j++){
dis[i][j]=dis[i][j-]+pos[j]-pos[(i+j)/];
}
dp[i][]=dis[][i];
} for(int j=;j<=m;j++){
for(int i=j;i<=n;i++){
for(int k=j-;k<i;k++){
dp[i][j]=min(dp[k][j-]+dis[k+][i],dp[i][j]);
}
}
}
printf("%d\n",dp[n][m]);
}
return ;
}

最新文章

  1. springmvc上传文件,抄别人的
  2. 一个简单的synchronized多线程问题、梳理与思考
  3. collection和collections区别
  4. oracle学习系列之四 (视图)
  5. javascript 文本框中,判断回车键触发事件 兼容IE&amp;FireFox
  6. leetcode@ [134] Gas station (Dynamic Programming)
  7. (转载)JavaScript中的Window窗口对象
  8. 转--DataTable 修改列名 删除列 调整列顺序
  9. git+Coding.netの小试牛刀
  10. 尚学堂 JAVA Day1 概念总结
  11. Jetty总览
  12. ZooKeeper之(三)工作原理
  13. Ajax原理一篇就够了
  14. 文本框监听事件blur()的简单使用
  15. subing用法
  16. python基础之作业2----购物车小练习
  17. DNS子域授权
  18. poj2594 机器人寻找宝藏(最小路径覆盖)
  19. 运行Keras版本的Faster R-CNN(1)
  20. 5步搭建GO环境

热门文章

  1. UVA.11464 Even Parity (思维题 开关问题)
  2. HDOJ.2072 单词数(map)
  3. Flex 布局教程:语法篇 【转】
  4. Ubuntu安装CUDA9.0 + cuDNN
  5. iOS-查询数据库--&gt;指定数据表中的当前数据行的总数量
  6. poj2060——Taxi Cab Scheme(最小路径覆盖)
  7. rm删除破折号 - 开头的文件
  8. bzoj 2124 等差子序列 树状数组维护hash+回文串
  9. [解决]java.io.IOException: Cannot obtain block length for LocatedBlock
  10. crontab 定期拉取代码