重点是要想到中位数贪心
然后就变成比较经典的分组DP了,只需要枚举最后一个邮局的位置即可
预处理w[i][j]表示在i~j之间的中位数上设置邮局的代价
f[i][j]表示前i个村庄设置j个邮局的最小代价
有
f[i][j]=min(f[k][j-1]+w[k][i])
j-1<=k<i 0<j<=i
初始化:
f=maxint
f[0][0]=0
即可
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,w[500][500],f[500][500],p[500];
int main()
{
memset(f,63,sizeof(f));
f[0][0]=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>p[i];
sort(p+1,p+n+1);
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
for(int k=i;k<=j;k++)
w[i][j]+=abs(p[k]-p[(i+j)/2]);
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
for(int k=j-1;k<i;k++)
f[i][j]=min(f[i][j],f[k][j-1]+w[k+1][i]);
cout<<f[n][m];
while(1);
return 0;
}