zoukankan      html  css  js  c++  java
  • 2020牛客寒假算法基础集训营3 J-牛牛的宝可梦Go(DP+Floyd)

    链接:https://ac.nowcoder.com/acm/contest/3004/J

    思路:

    先用flyod预处理出dis[i][j]表示从i到j点的最短距离

    之后开始DP,dp[i]表示出现i个精灵可收获的最大战斗力

    那么dp[i]得转移方程为dp[i]=max(dp[i],dp[i-j]+a[i].val) 表示在i之前j个出现的宝可梦的编号

    那么这样的时间复杂度就会为K2,但是我们可以发现,图上任意两点之间的距离都小于等于200,所以j最大只能为200,因此复杂度就降为O(200*K)

    注意还要判断两个宝可梦出现的时间差要大于等于两点之间的距离

    #include<iostream>
    #include<algorithm>
    #include<cstring>
     using namespace std;
     typedef long long ll;
     const int maxn=1e5+10;
     const int inf=0x3f3f3f3f;
     int dis[205][205],n,m,u,v,k;
     ll ans=0,dp[maxn];
     struct pok{
         int t,pos,v;
     }a[maxn];
     int cmp(pok a,pok b){return a.t<b.t;}
     void floyd()
     {
          for(int k=1;k<=n;++k)
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
     }
     int main()
     {
         scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) 
                dis[i][j]= i==j?0:inf;
         for(int i=1;i<=m;i++){
             scanf("%d%d",&u,&v);
             dis[u][v]=dis[v][u]=1;
         }
        floyd();
        scanf("%d",&k);
        for(int i=1;i<=k;i++)
            scanf("%d%d%d",&a[i].t,&a[i].pos,&a[i].v);
        sort(a+1,a+1+k,cmp);
        a[0].t=0,a[0].pos=1,a[0].v=0;
        for(int i=1;i<=k;i++){
            dp[i]=-inf;
            for(int j=1;j<=200&&i>=j;j++){
                if(a[i].t-a[i-j].t>=dis[a[i].pos][a[i-j].pos])
                    dp[i]=max(dp[i],dp[i-j]+a[i].v);
            }
            ans=max(dp[i],ans);
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    下载安装Git,学习笔记
    php面试相关整理
    2.5 DQL 分组查询
    2.4 DQL 常见函数
    2.3 DQL 排序查询
    2.2 DQL 条件查询
    2.1 DQL 基础查询
    1.2 MySQL的介绍
    1.1 数据库的相关概念
    2019年JavaEE学习线路
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12292925.html
Copyright © 2011-2022 走看看