邮局--dp经典问题
来源:互联网 发布:edg淘宝官方旗舰店衣服 编辑:程序博客网 时间:2024/04/29 17:27
题目:http://poj.org/problem?id=1160
题意: 一些村庄被建立在一条笔直的高速公路边上,我们用一条坐标轴来描述这条高速公路,每一个村庄的坐标都是整数,没
有两个村庄坐标相同。两个村庄间的距离,定义为它们的坐标值差的绝对值。我们需要在一些村庄建立邮局——当然,并不是每
一个村庄都必须建立邮局,邮局必须被建立在村庄里,因此它的坐标和它所在的村庄坐标相同。每个村庄使用离它最近的那个
邮局,建立这些邮局的原则是:所有村庄到各自所使用的邮局的距离总和最小。
你的任务是编写一个程序,在给定了每个村庄坐标和将要建立的邮局数之后,按照上述原则,合理地选择这些邮局的位置。
求出的所有村庄到距离它最近的邮局的距离总和.
分析:给定一个序列,假设我们要建一个邮局,那么一定是在这个序列的中点,所以我们可以先预处理出序列区间[l,r]之间建立
一个邮局的最短距离和w[l][r],然后用dp[i][j]表示到i个村庄建立j个邮局的最短距离和,那么就有状态转移方程:
#include <iostream>#include <string.h>#include <stdio.h>using namespace std;const int INF = ~0U>>1;const int N = 305;int w[N][N];int dp[N][35];int a[N];int n,m;void Init(int a[],int n){ memset(w,0,sizeof(w)); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) w[i][j] = w[i][j-1] + a[j] - a[(i+j)>>1];}int Work(){ for(int i=1;i<=n;i++) { dp[i][i] = 0; dp[i][1] = w[1][i]; } for(int j=2;j<=m;j++) { for(int i=j+1;i<=n;i++) { dp[i][j] = INF; for(int k=j-1;k<i;k++) dp[i][j] = min(dp[i][j],dp[k][j-1] + w[k+1][i]); } } return dp[n][m];}int main(){ while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); Init(a,n); printf("%d\n",Work()); } return 0;}
- 邮局--dp经典问题
- uva 662 (经典DP邮局问题)
- ♥Vijos 1242-邮局问题【经典DP】
- 邮局问题(DP)
- [IOI2000][DP]邮局问题
- POJ 1160:Post Office 邮局经典DP
- DP 【POJ1160】POST OFFICE 邮局问题
- 邮局问题
- 邮局选址问题
- 邮局选址问题
- 邮局选址问题
- 邮局选址问题
- shu_1241 邮局选址问题
- 邮局选址问题
- 邮局选址问题
- 邮局选址问题
- POJ1160 邮局问题
- 邮局贴邮票问题
- 成为一名PHP专家其实并不难
- UVA 10397 - Connect the Campus(最小生成树)
- 最短路径-Dijkstra(poj 1135)
- Java NIO Tutorial 2- Java NIO Overview
- Linux内核模块编程入门-4(Licensing和Module Documentation)
- 邮局--dp经典问题
- 面积
- (Relax 数论1.22)POJ 1905 Expanding Rods
- 11月23日
- ubuntu12.04安装jdk7
- 设置linux自动启动和关闭tomcat
- UVA 10099 - The Tourist Guide(floyd)
- java双向划分的快速排序
- Ubuntu实践(9) : core文件的来龙去脉