链接: 原题链接
题目描述
在一个地图上有N个地窖(N≤20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
输入格式
有若干行。
第11行只有一个数字,表示地窖的个数N。
第22行有N个数,分别表示每个地窖中的地雷个数。
第33行至第N+1行表示地窖之间的连接情况:
第33行有n−1个数(0或1),表示第一个地窖至第2个、第3个、…、第n个地窖有否路径连接。如第3行为1 1 0 0 0 … 011000…0,则表示第1个地窖至第2个地窖有路径,至第3个地窖有路径,至第4个地窖、第5个、…、第n个地窖没有路径。
第4行有n-2个数,表示第二个地窖至第3个、第4个、…、第n个地窖有否路径连接。
… …
第n+1行有1个数,表示第n−1个地窖至第n个地窖有否路径连接。(为0表示没有路径,为1表示有路径)。
输出格式
有两行
第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。
第二行只有一个数,表示能挖到的最多地雷数。
输入输出样例
输入
5
10 8 4 7 6
1 1 1 0
0 0 0
1 1
1
输出
1 3 4 5
27
说明/提示
【题目来源】
NOIP 1996 提高组第三题数
思路讲解
本题可以用DFS和DP来做,暂且只讲解DFS做法。
要求可挖掘的最大地雷数,由于路径是单向的,所以每个地雷只能向其后面的地雷搜索。不妨从每一个地雷开始暴力搜索。
代码实现
#include<bits/stdc++.h>
using namespace std;
const int MAXN=105;
int n,maxnn=-99999,geshu;
int a[MAXN],m[MAXN][MAXN],v[MAXN],f[MAXN],ans[MAXN];
void DFS(int x,int step,int sum);
bool check(int x)//是否走下去,走不下去,结算
{
for(int i=1;i<=n;i++)
{
if(m[x][i]&&!v[i]) return false;
}
return true;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n-1;i++)
for(int j=i+1;j<=n;j++)
scanf("%d",&m[i][j]);
for(int i=1;i<=n;i++)
{
v[i]=1;
f[1]=i;
DFS(i,1,a[i]);
v[i]=0;
}
for(int i=1;i<=geshu;i++)
printf("%d ",ans[i]);
printf("\n%d",maxnn);
}
void DFS(int x,int step,int sum)//x地雷已选上,继续向后搜索
{
if(check(x))
{
if(maxnn<sum)
{
maxnn=sum;
for(int i=1;i<=step;i++)
ans[i]=f[i];
geshu=step;
}
return;
}
for(int i=x+1;i<=n;i++)
{
if(m[x][i]==1&&v[i]==0)
{
v[i]=1;
f[step+1]=i;
DFS(i,step+1,sum+a[i]);
v[i]=0;
}
}
}
加油啊少年!!!