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
*/

 

posted @ 2020-05-16 13:12  mohari  阅读(202)  评论(0编辑  收藏  举报