书本整理
Time Limit:10000MS Memory Limit:65536K
Total Submit:10 Accepted:7
Case Time Limit:1000MS
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行,每行两个整数值a和b,分别表示一本书的高度(a)和宽度(b),它们均小于200。
Output
一行一个整数,表示去掉k本书后,书架的最小凌乱值。
Sample Input
4 1
1 2
2 4
3 1
5 3
Sample Output
3
Hint
【数据范围】
30%的数据,n<=20。 100%的数据,n<=100,k
做法:dp f[i,j]=min(f[l,j-1]+abs(y[l]-y[i]))
代码如下:
var
f:array[0..200,0..200] of longint;
x,y:array[0..200] of longint;
n,k,i,j,l,ans:longint;
procedure init;
var
i:longint;
begin
readln(n,k);
for i:=1 to n do
readln(x[i],y[i]);
end;
procedure paixu;
var
i,j,t:longint;
begin
for i:=1 to n do
for j:=1 to n do
if i<>j then
begin
if x[i]<x[j] then
begin
t:=x[i]; x[i]:=x[j]; x[j]:=t;
t:=y[i]; y[i]:=y[j]; y[j]:=t;
end;
end;
end;
begin
init;
paixu;
for i:=2 to n do
for j:=2 to n-k do
begin
if j>i then break;
f[i,j]:=maxlongint;
for l:=j-1 to i-1 do
if f[i,j]>f[l,j-1]+abs(y[l]-y[i]) then begin
f[i,j]:=f[l,j-1]+abs(y[l]-y[i]);
end;
end;
ans:=maxlongint;
for i:=n-k to n do
if ans>f[i,n-k] then ans:=f[i,n-k];
writeln(ans);
end.