DP POJ1160

题意:

题目链接

  有一排村庄,坐标表示村庄的位置。如(1、4、6、10)表示:在这几个点有村庄。现在要在这一排村庄中建立邮局,使得其它村庄到他们最近邮局的距离总和最小。

其中邮局有V个(V<=300),邮局有P个(P<=30)。问怎么设置邮局位置,求出最小距离。

解法:

1.表示方法

  • dp[i][j] : 表示前 i 个村庄 建 j 个邮局时距离最小值。
  • sum[i][j]: 表示第 i 个村庄到第 j 个村庄建一个邮局的最小距离。

2. 递推公式的由来

这个题目有点类似于矩阵连乘问题。要求dp[i][j],假设从k位置断开,前 k 个村庄建 j?1个邮局,后面k+1 到 i 建一个邮局,然后求出断开位置使dp[i][j] 最小。所以递推关系式如下:

  • dp[i][j]=min(dp[i][j],dp[k][j?1]+sum[k+1][i]);

3.sum[i][j]的递推

在i 和 j之间建一个邮局,显然建在中位数的村庄位置时最小。因为题中村庄的位置已经从小到大排好序,因此只要求出中位数村庄即可(这里与村庄的位置大小无关)。

  • 如果村庄有奇数个,比如有三个村庄:x1,x2,x3, x1到x2的距离为s1,x2到x3的距离为s2, 显然建在x2时距离最小为:s1+s2。(可以自己造几个case看看).
  • 如果村庄个数为偶数个,那么建在中间两个位置的距离是一样的。比如:x1,x2,x3,x4, x1到x2的距离为s1,x2到x3的距离为s2,x3到x4的距离为s3,那么建在中间两个村庄的距离是一样的。建在x2:s1+2?s2+s3,

    建在x3:s1+2?s2+s3。 建在x1: 3?s1+2?s2+s3。

  • 因此:在i到j之间建一个邮局的最小距离等于在i到j?1之间建一个邮局的距离最小值加上j点到中位数村庄的距离。即:sum[i][j]=sum[i][j]+x[j]?x[(i+j)/2]

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

int dp[300+1][300+1],sum[300+1][300+1];
int s[300+1];
int INF = 100000000;

int main()
{
    int V,P;
    scanf("%d%d",&V,&P);
    memset(dp,sizeof(dp),0);
    memset(sum,sizeof(sum),0);
    memset(s, sizeof(s), 0);
    for(int i = 1; i<=V; i++)
        scanf("%d",&s[i]);
    for(int i = 1; i<V; i++){
        for(int j = i+1; j<=V; j++)
            sum[i][j] = sum[i][j-1] + s[j] - s[(i+j)/2];
    }
    for(int i = 1; i<=V; i++)
        dp[i][1] = sum[1][i];
    for(int j = 2; j<=P; j++){
        for(int i = 1; i<=V; i++){
            dp[i][j] = INF;
            for(int k = 1; k<=i; k++)
                dp[i][j] = min(dp[i][j] ,dp[k][j-1]+sum[k+1][i]);
        }
    }
    printf("%d\n",dp[V][P]);
    return 0;
}

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

时间: 2024-10-19 16:58:30

DP POJ1160的相关文章

区间DP POJ1160村庄邮局问题

POJ1160 题目大意:一系列村庄在一维坐标系上有序的排列,建设p个邮局,问各个村庄到邮局的最短距离和. 线性区间DP问题 dp数组的值为最短/最优距离 村庄和邮局为限制 dp[i][j]表示前i个村庄有j个邮局的最优解 分析最小子问题可得前i个村庄有1个邮局的最优解--中间的村庄 所以分解区间dp[i][j] = min(dp[i][j],dp[k][j-1] + sum[k+1][i]) sum[i][j]数组表示从i到j村庄放一个邮局的最优解 j,i,k的遍历,最终得到最优解 外层遍历的

poj1160 dp

1 //Accepted 564 KB 63 ms 2 //和hdu1227一样 3 //dp[i][j]=min(dp[i][j],dp[k][j-1]+cost[k+1][i]) 4 //初始化条件,dp[0][0]=0; 5 //dp[i][0]=inf;i>=1; 6 #include <cstdio> 7 #include <cstring> 8 #include <iostream> 9 using namespace std; 10 const in

POJ1160 Post Office[序列DP]

Post Office Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18680   Accepted: 10075 Description There is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each vill

【DP|数学+预处理】POJ-1160 Post Office

Post Office Time Limit: 1000MS Memory Limit: 10000K 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 coord

poj1160(区间DP)

题目链接:http://poj.org/problem?id=1160 题意:一个公路上有n个村庄,要在一些村装建m个邮寄站,邮寄站必须建在村庄上,通过合理的选择m个建造地点,使得每个村到自己最近的邮寄站的距离和最小. 解法:这个要想到,对于i-j区间建一个邮寄站,最优方案是建在中间的村庄.那么可以预处理所有的cost[i][j]表示i-j建一个站的最小距离和.dp[i][j]表示前i个村庄建j个站的最小距离和.转移是这样:dp[i][j]=min(dp[k-1][j-1]+cost[k][i]

POJ1160 Post Office (四边形不等式优化DP)

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 dista

DP总结 ——QPH

常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一头压入元素. 队列中维护的是两个值.一个是位置,这和k的范围有关系,另外一个是f(k)的值,这个用来维护单调性,当然如果f(k)的值可以利用dp值在O(1)的时间内计算出来的话队列中可以只维护一个表示位置的变量. 枚举到一个i的时候,首先判断队首元素的位置是否已经不满足k的范围了,如果不满足就将队首

【poj1160】 Post Office

http://poj.org/problem?id=1160 (题目链接) 题意 按照递增顺序给出一条直线上坐标互不相同的n个村庄,要求从中选择p个村庄建立邮局,每个村庄使用离它最近的那个邮局,使得所有村庄到各自所使用的邮局的距离总和最小. Solution 经典dp方程: 其中f[i][j]表示前j个村庄,放置i个邮局的最优方案.w[i][j]表示在i到j的村庄放置一个邮局,i~j的村庄到这个邮局的总距离.考虑如何求解w[i][j],因为只放置一个邮局,所以一定是放在最中间的那个点上,所以邮局

POJ1160

再次使用强大的四边形优化dp f[i][j]=max(f[k][j-1]+w[k+1][i]) 其中f[i][j]表示前i个村落有j个邮电局,w[i][j]表示[i,j]区间上安装一个邮电局最短路径和 其中w[i][j]邮电局必然是安装在(i+j)/2(中位数)的村落中,若(i+j)/2不为整数,则中间两个村落都可以.证明可以看<算法导论> 至于四边形不等式,这次,可以直接容易得到 s[i][j-1]<=s[i][j]<=s[i+1][j] 稍微证明下就可以出来,凭感觉都是对的.