码迷,mamicode.com
首页 > 其他好文 > 详细

poj1160 Post Office 四边形不等式

时间:2014-05-21 16:30:14      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:poj1160   四边形不等式   

在一条直线上有n个村庄,选出m个村庄,在其中每个村庄建立一个邮局,要求每个村庄到最近邮局的距离和最小。


f[i][j]:在前i个村庄中建立j个邮局的最小耗费
dis[i][j]:在第i个村庄到第j个村庄中建立1个邮局的最小耗费
那么就有转移方程:f[i][j] = min(f[i][j],f[k][j-1]+dis[k+1][i]) DP的边界状态即为f[i][1] = dis[1][i]; 所要求的结果即为f[n][m];

然后就说说求dis数组的优化问题,可以假定有6个村庄,村庄的坐标已知分别为p1,p2,p3,p4,p5,p6;那么,如果要求dis[1][4]的话邮局需要建立在2或者3处,
放在2处的消耗为p4-p2+p3-p2+p2-p1=p4-p2+p3-p1
放在3处的结果为p4-p3+p3-p2+p3-p1=p4+p3-p2-p1,
可见,将邮局建在2处或3处是一样的。现在接着求sum[1][5],现在处于中点的村庄是3,那么1-4到3的距离和刚才已经求出了,即为dis[1][4],所以只需再加上5到3的距离即可。
同样,求dis[1][6]的时候也可以用dis[1][5]加上6到中点的距离。
所以有递推关系:dis[i][j] = dis[i][j-1] + p[j] -p[(i+j)/2]

用四边形不等式优化了一下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 1000
#define INF 100000000
using namespace std;
int n,m,i,j,k,p[N],dis[N][N],f[N][N],s[N][N];
void Init()  //初始化 
{
    for (i=1; i<=n; i++)
        for (j=1; j<=n; j++)
            f[i][j]=INF;
    for (i=1; i<=n; i++)    
        f[i][1]=dis[1][i];
    for (i=1; i<=m; i++)
        s[n + 1][i]=n;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (i=1; i<=n; i++)    scanf("%d",&p[i]);
    for (i=1; i<=n; i++)
        for (j=i+1; j<=n; j++)
            dis[i][j]=dis[i][j - 1] + p[j] - p[(i + j) >> 1];
    Init();    
    for (j=2; j<=m; j++)
        for (i=n; i>j; i--)
            for (k=s[i][j - 1]; k<=s[i + 1][j]; k++)
            {
                int t=f[k][j - 1] + dis[k + 1][i];
                if (f[i][j] > t)
                {
                    f[i][j]=t;
                    s[i][j]=k;
                }
            }
    printf("%d",f[n][m]);
    return 0;
}


poj1160 Post Office 四边形不等式,布布扣,bubuko.com

poj1160 Post Office 四边形不等式

标签:poj1160   四边形不等式   

原文地址:http://blog.csdn.net/dream_epic/article/details/26394681

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!