您的位置:首页 > 其它

【dp】有向直线k中值问题

2011-09-02 23:07 941 查看
问题描述:

给定一条有向直线L以及L上的n+1个点x0 < x1 <...< xn。有向直线L上的每个点都有一个权 w(xi);每条有向边(xi,xi-1)也都有一个非负边长d(xi,xi-1)。有向直线L上的每个点xi可以看作 客户,其服务需求量为w(xi)。每条边(xi,xi-1)的边长d(xi,xi-1)可以看作运输费用。如果在点
xi处未设置服务机构,则将点xi处的服务需求沿有向边转移到点xj处服务机构需付出的服务转 移费用为w(xi)*d(xi,xj)。在点x0处已设置了服务机构,现在要在直线L上增设k处服务机构, 使得整体服务转移费用最小。

编程任务:

对于给定的有向直线L,编程计算在直线L上增设k处服务机构的最小服务转移费用。

数据输入:

输入的第1行有1个正整数n,表示有向直线L上除了点x0外还有n个点 x0 < x1 <…< xn 。接下 来的n行中,每行有2个整数。第i+1行的2个整数分别表示w(x n-i-1)和d(xn-i-1,xn-i-2)。

结果输出:

输出计算的最小服务转移费用。

样例:

9

1 2

2 1

3 3

1 1

3 2

1 6

2 1

1 2

1 1

26

核心思想:

minco[i,j]表示在前i个点中设置j个服务机构的最小费用,则minco[i,j]=min{minco[k-1,j- 1]+w[t]*dist[t,k]},其中dist[t,k]表示从点Xt到点Xk的有向路径的长度

var
f:array[0..20010]of longint;
dist,wt,swt:array[0..20010]of longint;
n,m:longint;
procedure init;
var
d,w,i:longint;
begin
dist[1]:=0;wt[0]:=0;swt[1]:=0;
readln(n,m);
readln(wt[1],dist[2]);
fori:=2 to n do
begin
readln(w,d);
wt[i]:=wt[i-1]+w;
dist[i+1]:=dist[i]+d;
swt[i]:=swt[i-1]+w*dist[i];
end;
end;
function getw(x,y:longint):longint;
begin
ifx>y then exit(0)
else exit((wt[y-1]-wt[x])*dist[y]-(swt[y-1]-swt[x]));
end;
procedure comp;
var
i,j,k,tmp:longint;
begin
fori:=1 to n do f[i]:=getw(0,i+1);
forj:=1 to m do
begin
for i:=n downto j+1 do
begin
f[i]:=getw(1,i+1);
for k:=2 to i do
begin
tmp:=f[k-1]+getw(k,i+1);
if tmp<f[i] then f[i]:=tmp;
end;
end;
for i:=1 to j do f[i]:=0;
end;
end;
begin
assign(input,'p322.in');reset(input);
assign(output,'p322.out');rewrite(output);
init;
comp;
writeln(f
);
close(input);close(output);
end.
题目来源:《算法设计与分析》第三章动态规划
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: