您的位置:首页 > 其它

POJ1160(Post Office)

2012-04-04 17:56 260 查看
题目链接

动态规划题。模型为给定一条直线上的n个整点坐标,在其中选取p个点作为警亭,使得其余的点到最近的警亭的距离之和最小(下面简称最小距离和)。对输入坐标排序后,用c[i][j]保存最后一个警亭设在第i点,且该点之前还有j个警亭的情况下,第一点到第i点的最小距离和。照此不难写出状态转移方程。

c[i][j]=max{c[k][j-1]+(min(d[i]-d[t],d[t]-d[k]),t=k+1...i-1),k=j-1...i-1}

View Code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INF 0x7fffff
#define MIN(a,b) ((a)<(b)?(a):(b))
int a[301],c[301][31],n,p;
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int f(int m,int k)
{
int i,j,tmp,min;
if(c[m][k]!=-1) return c[m][k];
if(k==0)
{
tmp=0;
for(i=0;i<m;i++)  tmp+=a[m]-a[i];
c[m][k]=tmp;
return tmp;
}
min=INF;
for(i=k-1;i<m;i++)
{
tmp=0;
for(j=i+1;j<m;j++)    tmp+=MIN(a[j]-a[i],a[m]-a[j]);
min=MIN(min,tmp+f(i,k-1));
}
c[m][k]=min;
return min;
}
int main()
{
int i,j,tmp,ans;
while(scanf("%d%d",&n,&p)!=EOF)
{
for(i=0;i<n;i++)    scanf("%d",&a[i]);
qsort(a,n,sizeof(a[0]),cmp);
memset(c,0xff,sizeof(c));
ans=INF;
for(i=p-1;i<n;i++)
{
tmp=0;
for(j=i+1;j<n;j++)    tmp+=a[j]-a[i];
ans=MIN(ans,tmp+f(i,p-1));
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: