题目描述
在一个地图上有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
AC代码
DFS
#include<bits/stdc++.h> ///记忆化搜索
#define ll long long
#define endl '\n'
using namespace std;
const int N=1e5+5;
vector<int>maze[55];
int p[55];
int vis[55],ans[55];
int n;
int maxl(int beg)
{
if(vis[beg]!=p[beg])
return vis[beg];
int len=maze[beg].size();
if(len==0||beg==n)
return p[beg];
int maxn=0;
for(int i=0;i<len;i++)
{
int k=maxl(maze[beg][i]);
if(k>maxn)
ans[beg]=maze[beg][i],maxn=k;
}
return vis[beg]+=maxn;
}
int main()
{
ios_base::sync_with_stdio(NULL);
cin.tie(NULL),cout.tie(NULL);
cin>>n;
for(int i=1;i<=n;i++)
cin>>p[i],vis[i]=p[i];
int t;
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=n-i;j++)
{
cin>>t;
if(t)
maze[i].push_back(i+j);
}
}
int maxn=0,l;
maxl(1);
for(int i=1;i<=n;i++)
{
if(vis[i]>maxn)
maxn=vis[i],l=i;
}
for(int i=l;i!=0;i=ans[i])
{
if(i!=l)
cout<<" ";
cout<<i;
}
cout<<endl<<maxn<<endl;
return 0;
}
DP
就是当前的地雷数加上他所能链接的地窖中的最大地雷数
转移方程
dp[i]=max(dp[i+j],dp[i]);
#include<bits/stdc++.h> ///dp
#define ll long long
#define endl '\n'
using namespace std;
const int N=1e2+5;
int dp[N];
int maze[N][N];
int ans[N];
int main()
{
ios_base::sync_with_stdio(NULL);
cin.tie(NULL),cout.tie(NULL);
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>dp[i];
for(int i=1;i<=n-1;i++)
for(int j=1;j<=n-i;j++)
cin>>maze[i][j];
int maxn=0,beg=1;
for(int i=n-1;i>=1;i--)
{
int m=0;///初始化为0,存在有地洞一个也连不了
for(int j=1;j<=n-i;j++)
{
if(maze[i][j])
dp[i+j]>m?(m=dp[i+j],ans[i]=i+j):m;
}
dp[i]+=m;
dp[i]>maxn?(maxn=dp[i],beg=i):maxn;
}
for(int i=beg;i!=0;i=ans[i])
{
if(i!=beg)
cout<<" ";
cout<<i;
}
cout<<endl<<maxn<<endl;
return 0;
}