题目描述
在一个地图上有N个地窖(N<=200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。
输入
第一行一个整数n表示有n个地窖
第二行有n个整数表示每个地窖的地雷数
以下有若干行,每行有两个数x,y表示x可以到y,保证x小于y。
最后一行有两个0,表示输入结束
输出
第一行输出挖地雷的顺序。
第二行为最多挖出的地雷数
样例输入
6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0
样例输出
3-4-5-6
34
思路分析
此题目宜用动态规划求解,从题目中的已知条件可得,‘1’节点必为起始节点,‘n’节点也同样必为终止节点,且每一个节点都只能朝比自己大的节点的方向前进,所以要看终止节点的挖地雷数目决定于比自己小的且能到自己的所有节点中挖地雷数目总和最大的那个,以此类推,可以推到第一个,所以有动态方程
G[i]=MAX{G[j]+F[i]}(i<j<=n)(a[j,i]<>0)
有此可以求解出程序。
参考程序
type node=record
x:longint;
father:longint;
end;
var a:array[1..500,1..500]of longint;
g:array[1..500]of node;
c:array[1..500]of longint;
i,j,k,l,n,max,p:longint;
begin
readln(n);
fillchar(g,sizeof(g),0);
fillchar(a,sizeof(a),0);
for i:=1 to n do
read(g[i].x);
readln(k,l);
while (k<>0) and (l<>0) do
begin
a[k,l]:=1;
readln(k,l);
end;
for i:=1 to n do{枚举从1前进到n的过程}
begin
max:=0;
p:=0;
for j:=1 to i do
begin
if a[j,i]<>0 then
if g[j].x>max then
begin
max:=g[j].x;
p:=j;
end;
end;
g[i].x:=g[i].x+max;
g[i].father:=p;{father节点记录前进过程}
end;
writeln(g[n].x);
{p:=n;
write(p,'-');
p:=g[p].father;
repeat
if g[p].father=0 then
writeln(p)
else write(p,'-');
p:=g[p].father;
until p=0;}{这样输出是倒着的,故不采用}
p:=n;
i:=1;
c[i]:=p;
repeat
p:=g[p].father;
inc(i);
c[i]:=p;
until g[p].father=0;
for j:=i downto 2 do
write(c[j],'-');
writeln(c[1]);
end.