loj#2333 「JOI 2017 Final」准高速电车

分析

我们发现到达一个点一定是先快车再准快车再慢车

于是快车将1-n分为多个区间

每次取出每个区间当前能到达的点的数量

选剩余时间贡献最大的的一个取得贡献并且再能到达的最远点建立准快车

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k,a,b,c,T,d[3010],t[3010],now[3010],Ans;
priority_queue<int>q;
signed main(){
    int i,j,k;
    scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&a,&b,&c,&T);
    for(i=1;i<=m;i++){
      scanf("%lld",&d[i]);
      if(i!=1)T-=(d[i]-d[i-1])*b;
      t[i]=T;
      now[i]=d[i];
    }
    for(i=1;i<m;i++){
      if(t[i]<0)continue;
      int x=min(d[i+1],now[i]+t[i]/a+1);
      Ans+=x-now[i];
      t[i]-=(x-now[i])*c;
      now[i]=x;
    }
    for(i=1;i<=k;i++)
      for(j=1;j<m;j++){
          if(t[j]<0)continue;
        int x=min(d[j+1],now[j]+t[j]/a+1);
        q.push(x-now[j]);
        t[j]-=(x-now[j])*c;
        now[j]=x;
      }
    for(i=1;i<=k-m&&!q.empty();i++)Ans+=q.top(),q.pop();
    if(T<0)Ans--;
    cout<<Ans;
    return 0;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/11611506.html