http://acm.pku.edu.cn/JudgeOnline/problem?id=1160
题意:有V个村庄,要在V个村庄上建立S也邮局,使得所有的村庄到他们最近的邮局的距离和最小。(邮局建在村庄里面,和村庄占据着同一个点)
代码 ::
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include <iostream>
#include <climits>
using namespace std;
#define MAXN 305
int weight[MAXN][MAXN],dist[MAXN][31],pos[MAXN];
//dist[i][j]表示有j个邮局控制前i个村庄的最小距离和
//weight[i][j]表示从第i个村庄到第j个村庄由一个邮局控制的最小距离和
int main()
{
int i,j,k,s,v,min;
while(scanf("%d%d",&v,&s)!=EOF)
{
for(i=1;i<=v;i++)
{
scanf("%d",&pos[i]);
}
//对输入排序
sort(pos+1,pos+v+1);
memset(weight,0,sizeof(weight));
//计算从第i个村庄到第j个村庄由一个邮局控制的最小距离和
for(i=1;i<=v;i++)
{
for(j=i; j<=v;j++)
{
for(k=i;k<=j;k++)
{
weight[i][j]+=abs(pos[k]-pos[(i+j)/2]);
}
}
}
//第一个邮局控制前i个村庄的最小距离和
for(i=1;i<=v;i++)
dist[i][1]=weight[1][i];
for(i=2;i<=s;i++)
{
for(j=i;j<=v;j++)
{
min=INT_MAX;
for(k=i-1;k<=j-1;k++)
{
//前i-1个邮局控制前k个村庄的最小距离+从第k+1个村庄到第j个村庄由一个邮局控制的最小距离和
if(dist[k][i-1]+weight[k+1][j]<min)
min=dist[k][i-1]+weight[k+1][j];
}
dist[j][i]=min;
}
}
printf("%d/n",dist[v][s]);
}
return 0;
}