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

问题描述:

 给定一条有向直线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
题目来源:《算法设计与分析》第三章动态规划

你可能感兴趣的:(动态规划)