动态规划-航线设置

问题描述:美丽的莱茵河畔,每边都分布着N个城市,两边的城市都是唯一对应的友好城市,现需要在友好城市开通航线以加强往来.但因为莱茵河常年大雾,如果开设的航线发生交叉现象就有可能出现碰船的现象.现在要求近可能多地开通航线并且使航线不能相交!

假如你是一个才华横溢的设计师,该如何设置友好城市间的航线使的航线数又最大又不相交呢?

分析:此问题可以演化成求最大不下降序列来完成.源程序如下:
ExpandedBlockStart.gifprogram dongtai;  {动态规划之友好城市航线设置问题}
None.gifvar
None.gif d:array[1..1000,1..4] of integer;
None.gif i,j,k,n,L,p:integer;
None.gif
ExpandedBlockStart.gif procedure print(L:integer);  {打印结果}
None.gif begin
None.gif writeLn('最多可设置的航线数是 : ',k);
None.gif repeat
ExpandedBlockStart.gif writeLn(d[L,1]:4,d[L,2]:4);  {输出可以设置航线的友好城市代码}
None.gif L:=d[L,4]
None.gif untiL L=0
None.gif end;
None.gif
None.gifbegin
None.gif writeLn('输入友好城市对数: ');
None.gif readLn(n);
ExpandedBlockStart.gif writeLn('输入友好城市对(友好城市放在同一行:');  {输入}
None.gif  for i:=1 to n  do
ExpandedBlockStart.gif readLn(d[i,1],d[i,2]);  {D[I,1]表示起点,D[I,2]表示终点}
None.gif  for i:=1 to n  do
None.gif begin
ExpandedBlockStart.gif d[i,3]:=1;  {D[I,3]表示可以设置的航线条数}
ExpandedBlockStart.gif d[i,4]:=0  {D[I,4]表示后继,即下一条航线从哪里开始设置,为0表示不能设置下一条航线}
None.gif end;
ExpandedBlockStart.gif for i:=n-1 downto 1  do  {从倒数第二个城市开始规划}
None.gif begin
ExpandedBlockStart.gif L:=0; p:=0;  {L表示本城市后面可以设置的航线数,P表示下条航线从哪个城市开始}
ExpandedBlockStart.gif  for j:=i+1 to n  do  {找出本城市后面可以设置的最大航线数和小条航线到底从哪个城市开始设置}
None.gif  if (d[i,2] L) then 
ExpandedBlockStart.gif  {如果本城市I的终点小于后面城市的终点(即不相交)}  {并且此城市后面可以设置的航线数大于L}
None.gif begin
ExpandedBlockStart.gif L:=d[j,3];  {那么L等于城市J的可以设置航线数}
ExpandedBlockStart.gif p:=j  {P等于可以设置下条航线的城市代码}
None.gif end;
ExpandedBlockStart.gif  if L>0 then  {如果本城市后面总共可以设置的航线数>0则}
None.gif begin
ExpandedBlockStart.gif d[i,3]:=L+1;  {本城市可以设置的航线数在下个城市可以设置航线数的基础上加1}
ExpandedBlockStart.gif d[i,4]:=p  {D[I,4]等于本城市后续城市的代码}
None.gif end
None.gif end;
ExpandedBlockStart.gif k:=d[1,3];  {K为可以设置最大航线数,假设初值为第一个城市可以设置的航线数}
ExpandedBlockStart.gif L:=1;  {L为城市代码,初值为第一个城市}
ExpandedBlockStart.gif  for i:=2 to n  do  {找出可以设置航线的最大值,赋值给K,同时L记下哪个可以设置最大航线数的城市代码}
None.gif  if d[i,3]>k then
None.gif begin
None.gif k:=d[i,3];
None.gif L:=i
None.gif end;
ExpandedBlockStart.gif  for i:=1 to n  do  {打印结果,因为有可能有多种方案,所以只要哪个城市可以设置的航线数等于最大值K就打印结果}
None.gif  if d[i,3]=k then print(i)
None.gif
None.gifend.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值