poj 1160
2015-01-04 21:01
274 查看
题意为给出n个村庄的坐标,问如何设立m个邮局,使得每个村庄离其最近邮局的总路程即总花费最小。
思路:
若只设立一个邮局,可知邮局设在村庄坐标中位数的位置是最优解。这个问题属于在n个东西中选出m个,求全局最优解的问题。自然想到dp。设立二维数组dp[i][j-1]表示i个邮局放入前j个村庄所需的最小费用。可得dp方程:dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) (i-1<=k<j)。cost[i][j]表示在村庄i到村庄j之间选一个村庄设立邮局的最小花费,即为村庄[i,j]中每个村庄到ij中位数村庄的距离和,可预处理得到.。转移方程的意义上是:枚举前i-1个邮局所占有的村庄区间,即为0到k,剩余的一个邮局在区间k+1到j,其最小花费为cost[i][j]。所有k种组合的最小值即为dp[i][j]的值。
cost 数组求解的过程中也存在一个递推式:cost[i][j]=cost[i][j-1]+vl[j]-vl[(i+j)/2],其中vl[i]表示第i+1个村庄的坐标。纸上画一画可知其正确性。
注意:dp[1][j]=cost[0][j]的初始化
思路:
若只设立一个邮局,可知邮局设在村庄坐标中位数的位置是最优解。这个问题属于在n个东西中选出m个,求全局最优解的问题。自然想到dp。设立二维数组dp[i][j-1]表示i个邮局放入前j个村庄所需的最小费用。可得dp方程:dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) (i-1<=k<j)。cost[i][j]表示在村庄i到村庄j之间选一个村庄设立邮局的最小花费,即为村庄[i,j]中每个村庄到ij中位数村庄的距离和,可预处理得到.。转移方程的意义上是:枚举前i-1个邮局所占有的村庄区间,即为0到k,剩余的一个邮局在区间k+1到j,其最小花费为cost[i][j]。所有k种组合的最小值即为dp[i][j]的值。
cost 数组求解的过程中也存在一个递推式:cost[i][j]=cost[i][j-1]+vl[j]-vl[(i+j)/2],其中vl[i]表示第i+1个村庄的坐标。纸上画一画可知其正确性。
注意:dp[1][j]=cost[0][j]的初始化
#include <cstdio> using namespace std; int dp[31][301]; int cost[301][301]; int vl[301]; int v,p; int main() { scanf("%d%d",&v,&p); for(int i=0;i<v;i++) scanf("%d",vl+i); for(int i = 0; i < v-1; ++i) for(int j=i+1;j<v;++j) cost[i][j]=cost[i][j-1]+vl[j]-vl[(i+j)/2];//预处理得到cost数组的值 for(int i=1;i<v;i++) dp[1][i]=cost[0][i];//dp初始化 for(int i=2;i<=p;i++) for(int j=i;j<v;j++) { int t=dp[i-1][i-1]+cost[i][j]; for(int k=i;k<j;k++) if(dp[i-1][k]+cost[k+1][j]<t) t=dp[i-1][k]+cost[k+1][j]; dp[i][j]=t; } printf("%d\n",dp[p][v-1]); return 0; }
相关文章推荐
- POJ 1160 题解
- poj 1160
- H - Post Office POJ - 1160
- poj 1160 Post Office(动态规划:较难)
- 【POJ 1160】Post Office
- poj 1160 Post Office(DP简单题)
- poj 1160 dp
- dp四边形优化 poj 1160 Post Office题解
- 【POJ】1160 Post Office
- POJ1160 dp
- POJ 1160 DP
- POJ 1160——Post Office
- [IOI2000][POJ1160]Post office
- POJ 1160 Post Office
- poj 1160Post Office
- POJ 1160 Post Office
- POJ 1160 Post Office (动态规划)
- POJ 1160 Post Office(DP)
- POJ1160 邮局问题
- POJ 1160 Post Office