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

传送门

题目描述

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

有若干行。

第111行只有一个数字,表示地窖的个数NNN。

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

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

第333行有n−1n-1n−1个数(000或111),表示第一个地窖至第222个、第333个、…、第nnn个地窖有否路径连接。如第333行为11000…01 1 0 0 0 … 011000…0,则表示第111个地窖至第222个地窖有路径,至第333个地窖有路径,至第444个地窖、第555个、…、第nnn个地窖没有路径。

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

… …

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

输出格式

有两行

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

第二行只有一个数,表示能挖到的最多地雷数。
输入输出样例
输入 #1

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

输出 #1

1 3 4 5
27

思路
一看到题目我就直接想到了dfs暴力搜索,自己搜了一遍但是不会记录路径,后来看了大佬的题解,才知道原来可以这样子记录路径,学到了,等会要去学一下dp的正规解法。

#include<iostream>
using namespace std;


bool f[21][21];//记录是否有路径相连
int a[21];//记录地雷数
int path[21],ans[21],cnt;//path记录路径,ans记录答案,cnt记录走了多少个点
bool b[21];//记录该点是否走过
int n;
int maxx;//记录最大地雷数
bool chck(int x)//检查是否还能往下挖
{
    
    
    for(int i=1;i<=n;i++)
    {
    
    
        if(f[x][i]&&!b[i])return false;
    }
    return true;
}
void dfs(int x,int stp,int sum)
{
    
    
    if(chck(x))
    {
    
    
        if(maxx<sum)
        {
    
    
            maxx=sum;
            cnt=stp;
            for(int i=1;i<=stp;i++)
            {
    
    
                ans[i]=path[i];
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
    
    
        if(f[x][i]&&!b[i])
        {
    
    
            b[i]=1;
            path[stp+1]=i;//记录路径
            dfs(i,stp+1,sum+a[i]);
            b[i]=0;
        }
    }
}
int main()
{
    
    
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    
    
        cin>>a[i];
    }
    for(int i=1;i<n;i++)
    {
    
    
        for(int j=i+1;j<=n;j++)
        {
    
    
            cin>>f[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
    
    
        b[i]=1;
        path[1]=i;
        dfs(i,1,a[i]);
        b[i]=0;
    }
    for(int i=1;i<=cnt;i++)
    {
    
    
        cout<<ans[i]<<" ";
    }
    cout<<endl<<maxx;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_51344983/article/details/112833341