Zju1196 Fast Food
有一个公司,在一条街上有N个快餐店,公司决定修K个仓库以满足这些快餐电的原料需求. 现在给出N个快餐店的横坐标(他们都在一条直线上面),要求修K个仓库,使得所有的快餐店离其对应的仓库的距离最短. 仓库需要建在快餐店内。
分析 from http://www.programfan.com/blog/article.asp?id=17344,人家是All Rights Reserved?
f是最小距离 i是仓库数 j是快餐店数 cost是中间仅1个仓库时的距离,在function c中,不难理解。 f[i,j]=min(f[i-1,k]+cost[k+1,j]) (i-1 <= k < j)
program zju1196;
var
n,k,t:longint;
i,j,l:longint;
d:array[1..200] of longint;
f:array[0..30,0..200] of longint;
cost:array[1..200,1..200] of longint;
function c(a,b:longint):longint;
var
temp,i,mid:longint;
begin
temp:=0;
mid:=(a+b) div 2;
for i:=a to b do temp:=temp+abs(d[i]-d[mid]);
c:=temp;
end;
begin
fillchar(f,sizeof(f),0);
t:=0;
while true do
begin
inc(t);
readln(n,k);
if n=0 then break;
fillchar(f,sizeof(f),0);
for i:=1 to n do readln(d[i]);
for i:=1 to n-1 do
for j:=i+1 to n do cost[i,j]:=c(i,j);
for i:=0 to k do
for j:=1 to n do f[i,j]:=999999999;
for i:=1 to k do
for j:=i to n do
for l:=i-1 to j-1 do
if f[i-1,l]+cost[l+1,j]&amp;amp;amp;amp;amp;amp;amp;amp;lt;f[i,j] then f[i,j]:=f[i-1,l]+cost[l+1,j];
writeln('Chain ',t);
writeln('Total distance sum = ',f[k,n]);
writeln;
end;
end.
可以预处理f[1,*],这样就可以用maxlongint了,更加稳妥。
program zju1196;
var
n,k,t:longint;
i,j,l:longint;
d:array[1..200] of longint;
f:array[0..30,1..200] of longint;
cost:array[1..200,1..200] of longint;
function c(a,b:longint):longint;
var
temp,i,mid:longint;
begin
temp:=0;
mid:=(a+b) div 2;
for i:=a to b do temp:=temp+abs(d[i]-d[mid]);
c:=temp;
end;
begin
fillchar(f,sizeof(f),0);
t:=0;
while true do
begin
inc(t);
readln(n,k);
if n=0 then break;
fillchar(f,sizeof(f),0);
for i:=1 to n do readln(d[i]);
for i:=1 to n-1 do
for j:=i+1 to n do cost[i,j]:=c(i,j);
for i:=2 to k do
for j:=1 to n do f[i,j]:=maxlongint;
for i:=1 to n do f[1,i]:=cost[1,i];
for i:=2 to k do
for j:=i to n do
for l:=i-1 to j-1 do
if f[i-1,l]+cost[l+1,j]<f[i,j] then f[i,j]:=f[i-1,l]+cost[l+1,j];
writeln('Chain ',t);
writeln('Total distance sum = ',f[k,n]);
writeln;
end;
end.
f还可以优化成一维数组:f:array[0..200] of longint;从后向前推即可,这样时间能从00:00.05降到00:00.04。
program zju1196;
var
n,k,t:longint;
i,j,l:longint;
d:array[1..200] of longint;
f:array[0..200] of longint;
cost:array[1..200,1..200] of longint;
function c(a,b:longint):longint;
var
temp,i,mid:longint;
begin
temp:=0;
mid:=(a+b) div 2;
for i:=a to b do temp:=temp+abs(d[i]-d[mid]);
c:=temp;
end;
begin
assign(input,'zju.in');
reset(input);
fillchar(f,sizeof(f),0);
t:=0;
while true do
begin
inc(t);
readln(n,k);
if n=0 then break;
f[0]:=0;
for i:=1 to n do readln(d[i]);
for i:=1 to n-1 do
for j:=i+1 to n do cost[i,j]:=c(i,j);
for i:=1 to n do f[i]:=cost[1,i];
for i:=2 to k do
for j:=n downto i do
begin
f[j]:=maxlongint;
for l:=j-1 downto i-1 do
if f[l]+cost[l+1,j]<f[j] then f[j]:=f[l]+cost[l+1,j];
end;
writeln('Chain ',t);
writeln('Total distance sum = ',f[n]);
writeln;
end;
close(input);
end.
comments powered by Disqus