P2196 挖地雷(dp)
https://www.luogu.com.cn/problem/P2196
给定每个点的地雷数目,再给定点能否直接到其他点的情况,求最大地雷的数目和其路径。典型dp题
如果j到i有边,有dp[i]=max(dp[i],dp[j]+a[i]);
路径存储有一个结构体,存储上一条边,最后逆序输出就好啦
ac代码如下
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<queue> #include<map> #include<string.h> using namespace std; typedef long long int ll; int n,k,m,b,t,t1,t2,t3,maxx=0; const int maxn=1e5+5; const int mod= 80112002; vector<vector<int> >v(25,vector<int>(25)); vector<int>a(maxn); struct node{ int pre,now; }p[25]; int dp[25]; int main() { scanf("%d",&n); for(int i=0;i<25;i++)v[i].clear();a.clear(); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); dp[i]=a[i]; p[i].now=i; p[i].pre=-1; } for(int i=1;i<=n-1;i++){ for(int j=1;j<=n-i;j++){ scanf("%d",&t); if(t==1){ v[i][i+j]=1; p[i+j].pre=i; } } } for(int i=2;i<=n;i++){ for(int j=1;j<=i;j++){ if(v[j][i]){ if(dp[i]<dp[j]+a[i]){ dp[i]=dp[j]+a[i]; p[i].pre=j; } } } } int maxx=-1,g=0; for(int i=1;i<=n;i++){ if(maxx<dp[i]){ g=i; maxx=dp[i]; } } int way[25];int k=0; while(p[g].pre!=p[g].now){ way[k++]=p[g].now; g=p[g].pre; } for(int i=k-1;i>=0;i--){ cout<<way[i]<<" "; } cout<<endl; cout<<maxx<<endl; return 0; } /* 5 10 8 4 7 6 1 1 1 0 0 0 0 1 1 1 */