书本整理
Description
小明的书架上放了很多书,为了使书架变得整洁,小明决定整理书架,他将所有书安高度大小排列,这样排了之后虽然整齐了许多,但小明发现,书本的宽度不同,导致书架看上去还是有些凌乱。小明将这个凌乱值定义为相邻两本书的宽度差的绝对值的和。
例如有4本书
1*2
5*3
2*4
3*1
小明将其排列整齐后的顺序是:
1*2
2*4
3*1
5*3
凌乱值为2+3+2=7。
于是小明决定拿掉其中的k本书,并使凌乱值最小。
已知每本书的高度都不一样。
Input
第一行两个数n和k,代表书的总数共有n 本,要求从中去掉k本书。(1=<n<=100,1<=k<n);
下面n行,每行两个整数值a和b,分别表示一本书的高度(a)和宽度(b),它们均小于200。
Output
一行一个整数,表示去掉k本书后,书架的最小凌乱值。
分析:f[i,j]表示前i本书保留j本书在书架上时的最小凌乱值,f[i,j]=min(f[o,j-1]+abs(a[o]-a[i])) (j<o<i)。
代码
const
maxn=100;
var
f:array[0..maxn,0..maxn] of longint;
a,b:array[0..maxn] of longint;
n,m,i,j,k,ans:longint;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
begin
readln(n,m);
for i:=1 to n do
readln(a[i],b[i]);
for i:=1 to n-1 do
for j:=i+1 to n do
if a[i]>a[j] then
begin
a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];
end;
for i:=2 to n do
for j:=2 to n-m do
begin
if j>i then break;
f[i,j]:=maxlongint;
for k:=j-1 to i-1 do
f[i,j]:=min(f[i,j],f[k,j-1]+abs(b[k]-b[i]));
end;
ans:=maxlongint;
for i:=n-m to n do
ans:=min(ans,f[i,n-m]);
writeln(ans);
end.