Description:
FJ有N(2<=N<=1,500)头牛编号为1到N,FJ新盖了S(N<=S<=1,000,000)个牛棚,编号为1到S,S个牛棚排成一排,相邻牛棚距离为1。
每个牛棚只能住一头牛,每头牛都选择了一个牛棚P_i来休息,当两头牛离得太近时就会变得很暴躁,FJ想移动一些牛到其他牛棚使得他们之间的间距尽可能大,同时FJ又希望这N-1个间距尽可能相似。
帮助FJ用最少的移动距离满足要求。
Input
第1行:两个空格隔开的整数N和S
第2到N+1行:第i+1行包含一个整数P_i
Output
输出一个整数表示最少移动距离。
Solution
典型DP.
使用了神奇的DP式.
若
D=s−1n−1
设
F[i,j]
为到第
i
头牛,有
则推出方程:
Fi,j=min(Fi−1,j,Fi−1,j−1)+abs(ei−(i−j−1)∗d−j∗(d+1)−1)
取值范围:
2≤i≤n
0≤j≤min((s−1)mod(n−1),i−1)
初值:
F=maxlongint3
F1,0=e1−1
Program
uses
math;
var
d,n,s,i,j,ans:longint;
e:array [1..1500] of longint;
f:array [0..1500,0..1500] of longint;
procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;
x:=y;
y:=t;
end;
procedure Qsort(l,r:longint);
var
m,i,j:longint;
begin
i:=l;
j:=r;
m:=e[(i+j) shr 1];
repeat
while e[i]<m do
inc(i);
while m<e[j] do
dec(j);
if I<=j then
begin
swap(e[i],e[j]);
inc(i);
dec(j);
end;
until i>j;
if i<r then
Qsort(i,r);
if l<j then
Qsort(l,j);
end;
begin
assign(input,'graze2.in');
assign(output,'graze2.out');
reset(input);
rewrite(output);
readln(n,s);
d:=(s-1) div (n-1);
for i:=1 to n do
readln(e[i]);
Qsort(1,n);
for i:=0 to n do
for j:=0 to n do
f[i,j]:=maxlongint div 3;
f[1,0]:=e[1]-1;
for i:=2 to n do
for j:=0 to min(i-1,(s-1) mod (n-1)) do
begin
f[i,j]:=min(f[i,j],f[i-1,j]+abs(e[i]-(i-j-1)*d-j*(d+1)-1));
if j>0 then
f[i,j]:=min(f[i,j],f[i-1,j-1]+abs(e[i]-(i-j-1)*d-j*(d+1)-1));
end;
writeln(f[n,(s-1) mod (n-1)]);
close(input);
close(output);
end.