P2196 挖地雷【dfs】

题目描述

在一个地图上有NN个地窖(N \le 20)(N≤20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。

输入格式

有若干行。

第11行只有一个数字,表示地窖的个数NN。

第22行有NN个数,分别表示每个地窖中的地雷个数。

第33行至第N+1N+1行表示地窖之间的连接情况:

第33行有n-1n−1个数(00或11),表示第一个地窖至第22个、第33个、…、第nn个地窖有否路径连接。如第33行为1 1 0 0 0 … 011000…0,则表示第11个地窖至第22个地窖有路径,至第33个地窖有路径,至第44个地窖、第55个、…、第nn个地窖没有路径。

第44行有n-2n−2个数,表示第二个地窖至第33个、第44个、…、第nn个地窖有否路径连接。

… …

第n+1n+1行有11个数,表示第n-1n−1个地窖至第nn个地窖有否路径连接。(为00表示没有路径,为11表示有路径)。

输出格式

有两行

第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。

第二行只有一个数,表示能挖到的最多地雷数。

输入输出样例

输入

5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1

输出

1 3 4 5
27

解题思路

dfs

首先这道题最先想到的就是暴力搜索了 ,存一个邻接矩阵表map,然后使用dfs,以每个点为起点搜索一遍,然后用dp[i]数组存储以i为终点到该点的最大地雷数,track[i]记录了到i点获取最大地雷数需要从哪点来。

#include<cstdio>
#define max(a, b)  (a)>(b)?a:b
int map[25][25];
int dp[25] = { 0 };  //i点为终点的最大地雷数
int track[25];         //从哪点过来有最大地雷数
int mine[25];         //每个地窖的地雷数
int n;

void dfs(int v, int c)   //v是当前点,c是过来点
{
	if (dp[c] + mine[v] > dp[v])
	{
		dp[v] = mine[v] + dp[c];
		track[v] = c;
	}
	for (int i = v+1; i <= n; i++)
	{
		if (map[v][i])
			dfs(i, v);
	}
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &mine[i]);
	}
	for (int i = 1; i < n; i++)
	{
		for (int j = i + 1; j <= n; j++)
		{
			scanf("%d", &map[i][j]);
		}
	}
	for(int i = 1;i<=n;i++)           //每个点为起点搜索一遍
		dfs(i, 0);
	int ans = 0, p = 0;
	for (int i = 1; i <= n; i++)
	{
		if (dp[i] > ans)
		{
			ans = dp[i];
			p = i;
		}
	}
	int cnt = 1;
	int tmp[25] = { p };
	while (track[p] != 0)   //路径
	{
		tmp[cnt++] = track[p];
		p = track[p];
	}
	for (int i = cnt - 1; i >=0; i--)
	{
		if (i != 0)
			printf("%d ", tmp[i]);
		else
			printf("%d\n", tmp[i]);
	}
	printf("%d\n", ans);
	return 0;
}

 

posted @ 2020-06-10 09:56  Hu_YaYa  阅读(25)  评论(0)    收藏  举报