算法:DP
分析:IOI2000的一道经典的DP题目,设dis[i,j]表示从i到j的所有点到i—j中点的距离和(其实这里也可以采用别的方式)。然后设f[i,j]为前i个村庄设了j个邮局后的距离的最小值,那么f[i,j]=min(f[i,j],f[k,j-1]+dis[k+1,i])。
program Vijos1242;
const
maxn=300;
maxm=30;
var
n,m:longint;
a:array [0..maxn] of longint;
dis:array [0..maxn,0..maxn] of longint;
f:array [0..maxn,0..maxm] of longint;
procedure init;
var
i:longint;
begin
readln(n,m);
for i:=1 to n do read(a[i]);
end;
procedure ycl;
var
i,j,k:longint;
begin
for i:=1 to n do
begin
for j:=1 to n do
begin
for k:=i to j do
inc(dis[i,j],abs(a[k]-a[(i+j) shr 1]));
end;
end;
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure main;
var
i,j,k:longint;
begin
fillchar(f,sizeof(f),100);
for i:=1 to n do f[i,1]:=dis[1,i];
for i:=1 to n do
begin
for j:=2 to m do
begin
if i>=j then
begin
for k:=1 to i-1 do
f[i,j]:=min(f[i,j],f[k,j-1]+dis[k+1,i]);
end;
end;
end;
end;
begin
assign(input,'VJ1242.in'); reset(input);
assign(output,'VJ1242.out'); rewrite(output);
init;
ycl;
main;
writeln(f[n,m]);
close(input); close(output);
end.