一本通 1262 挖地雷(基础DP 与 城市交通路网思路类似 不过值在点上)

二次信任 提交于 2019-12-10 04:57:40

1262:【例9.6】挖地雷

【题目描述】
在一个地图上有nn个地窖(n≤200n≤200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,且保证都是小序号地窖指向大序号地窖,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任意一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。

【输入】
第一行:地窖的个数;
第二行:为依次每个地窖地雷的个数;
下面若干行:
xiyi //表示从xi可到yi,xi<yi。
最后一行为"0000"表示结束。
【输出】
k1−k2−…−kvk1−k2−…−kv //挖地雷的顺序
挖到最多的雷。
【输入样例】
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、题目中所说的“规定路径都是单向的,且保证都是小序号地窖指向大序号地窖”也就是说,在确定这个点的最大值的时候需要借助的各种能够到达的路径的小序号的点一定是可以确定值的。
2、不同的是初始化,本道题的各个路径的起点不一定相同,而且值是在点上,不再是在路径上,所以如果没有前驱的话(也就是它是一个起点)初始值应该是这个点的值。
3、本道题中,a数组记录各个点的原本地雷值,b数组描绘邻接矩阵的二维数组,c数组记录前驱,d数组记录到达每个重点的最优值(一条路径中所遇到的最大的地雷数)

具体思路可以参数博客城市交通路网https://blog.csdn.net/qq_40575034/article/details/103458380,已经在里面将那道题的思路集体讲述了,除上述问题需要注意之外,思路与之相同。

代码:

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
/*并规定路径都是单向的,且保证都是小序号地窖指向大序号地窖,
也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径*/ 
//思路:类型城市交通网 只不过需要将二维数组自己设计出来 且起点可能有多个,终点需要自己找 

int a[201];//记录地窖中地雷的个数 
int b[201][201];//二维数组记录图 行号是各个起点 列号是终点 
int d[201];//记录到这个终点的能够经过地雷的最大值 
int c[201];//记录前驱 
int main()
{
 int n;
 cin>>n;
 memset(b,0,sizeof(b)); 
 memset(d,0,sizeof(d)); 
 memset(c,0,sizeof(c)); 
 for(int i=1;i<=n;i++)
 {
  cin>>a[i];
  } 
 int q,z;//起点 终点 
 while((scanf("%d%d",&q,&z))&&q!=0&&z!=0)
 {
  b[q][z]=1;
  } 
 int max_z=0;
 int xiabiao=0;
 for(int j=1;j<=n;j++)//遍历各个终点值  因为永远从序号小到大走,所以前面的点一定确定了值的 
 {
  max_z=0; 
  for(int i=1;i<=n;i++)
  {
   if(b[i][j]!=0)//要找能走过来的
   {
    b[i][j]=d[i]+a[j];
    if(max_z<b[i][j])
    {
     max_z=b[i][j];
     xiabiao=i;
    }
    } 
  }
  if(max_z!=0)//如果能够有到来的点 
  {
   d[j]=max_z;
   c[j]=xiabiao; 
   } 
  else
  {
   d[j]=a[j];//最大值就是其自己拥有的地雷 
   c[j]=0;
  }
  
 }
 
 //输出
 int max_xia; 
 max_z=0; 
 for(int j=1;j<=n;j++)//找出所求路径的终点 
 {
  if(d[j]>max_z)
  {
   max_z=d[j];
   max_xia=j;
  }
  } 
 int dayin[201];
 int num=0;
 int p=max_xia;
 while(c[p])
 {
  num++;
  dayin[num]=c[p];
  p=c[p];
 }
 for(int i=num;i>=1;i--)
 {
  printf("%d-",dayin[i]);
 }
 cout<<max_xia<<endl;
 
 cout<<max_z; 
 
 return 0;
 } 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!