P2196 [NOIP1996 提高组] 挖地雷 【记搜】
洛谷 P2196 -> Click Here
题意
与 P1434 滑雪 类似
一个有向图上有N个点,每个点有一个地雷数,询问从任意一点出发,最多能收集多少地雷并打印最优解路径
题面小坑点:边为有向边
思路
记忆化搜索
- \(A[i]\) :点 \(i\) 的地雷数
- \(tab[i][j]\) :点 \(i\) 到点 \(j\) 是否有路径
- \(f[i]\) :从点 \(i\) 出发最多收集到的地雷数
- \(vis[i]\) :点 \(i\) 是否被访问过
- \(nxt[i]\) :用来存储路径,打印路径时点 \(i\) 的下一个点
转移方式:\(f[i]=max(f[i],A[i]+f[i所能够到达的点])\)
code
#include<bits/stdc++.h>
using namespace std;
int A[1005],tab[22][22],f[25],vis[25],nxt[25],n;
int go(int x){
vis[x]=1;
if(f[x]) return f[x];
f[x]=A[x];
for(int i=x+1;i<=n;i++)
if(tab[x][i]&&vis[i]==0){
int to=A[x]+go(i);
if(to>f[x]){
nxt[x]=i;
f[x]=to;
}
}
return f[x];
}
void out(int x){
printf("%d ",x);
if(!nxt[x]) return;
out(nxt[x]);
return;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&A[i]);
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
scanf("%d",&tab[i][j]);
int ans=0,sta;
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++) vis[i]=0;
int to=go(i);
if(to>ans){
ans=to;
sta=i;
}
out(sta);
printf("\n%d\n",ans);
return 0;
}

浙公网安备 33010602011771号