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;
    }
  • 相关阅读:
    VIM 文本对象选择
    XLA优化实例
    TVM/Relay 的 PartitionGraph()(mod) 函数讨论整理
    OpenCL通用异构开放环境
    LLVM IR 理解
    vue——请求跨域时,vcli2/vcli3设置代理
    【转】SQL 21天实战练习
    bash命令
    linux命令
    jenkins技术
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12292925.html
Copyright © 2011-2022 走看看