挖地雷

题目描述

在一个地图上有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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值