洛谷题解P2196 [NOIP1996 提高组] 挖地雷

目录

题目链接:

题目描述

输入格式

输出格式

代码


题目链接:

P2196 [NOIP1996 提高组] 挖地雷 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目描述

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

输入格式

有若干行。

第 1 行只有一个数字,表示地窖的个数 N。

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

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

第 3 行有 n−1 个数(0或 1),表示第一个地窖至第 2 个、第 3 个 …… 第 n 个地窖有否路径连接。如第 3 行为 11000⋯0,则表示第 1 个地窖至第 2 个地窖有路径,至第 3 个地窖有路径,至第 4 个地窖、第 5 个 …… 第 n 个地窖没有路径。

……

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

输出格式

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

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

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long  
#define ull unsigned long long
int dp[21];
int boom[21];
int map1[21][21];
int visit[21];
int max_visit;
int n,m;
int max1=-1;
void DFS(int x){
	if(visit[x]) DFS(visit[x]);
	cout<<x<<" ";
}
void solve() {
	
	cin>>n;
	
	for(int i=1;i<=n;i++)
	{
		cin>>boom[i];
		map1[i][i]=0;
	}
	for(int i=1;i<=n-1;i++)
	{
		
		for(int j=i+1;j<=n;j++)
		{
			cin>>m;
			map1[i][j]=m;
			map1[j][i]=m;
		}
	}
	fill(dp,dp+n+1,0);
	fill(visit,visit+n+1,0);
	for(int i=1;i<=n;i++)
	{
		dp[i]=boom[i];
		for(int j=i-1;j>=1;--j)
		{
			if(map1[j][i]&&dp[i]<dp[j]+boom[i])
			{
				dp[i]=dp[j]+boom[i];
				visit[i]=j;
			}
		}
		if(dp[i]>max1)
		{
			max1=dp[i];
			max_visit=i;
		}
	}
	DFS(max_visit);
	cout<<endl<<max1;
} 

signed main() {
    ios::sync_with_stdio(0);
    cout.tie(0);
    cin.tie(0);

    ll t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}