2018.10.29-dtoj-4005-高速列车

JOI 铁路公司是 JOI 国唯一的铁路公司。

在某条铁路沿线共有 N座车站,依次编号为 1...N。 目前,正在服役的车次按照运行速度可分为两类:高速电车(简称快车)与普通电车(简称慢车)。

  • 慢车每站都停。乘慢车时,对于任意一座车站 i(1<=i<N),车站 ii 到车站i+1i+1 用时均为 A
  • 快车只在车站 S1,S2,,SM​​ 停车 (1=S1<S2<<SM=N)。乘快车时,对于任意一座车站 i(1<=i<N),车站 到车站 i+1用时均为 B

JOI 铁路公司现拟开设第三类车次:准高速电车(简称准快车)。乘准快车时,对于任意一座车站 i(1<=i<N),车站 i 到车站 i+1 用时均为 C。准快车的停站点尚未确定,但满足以下条件:

  • 快车在哪些站停车,准快车就得在哪些站停车。
  • 准快车必须恰好有 K 个停站点。

JOI 铁路公司希望,在 T 分钟内(不含换乘时间),车站 1 可以抵达的车站(不含车站 1)的数量 尽可能多。但是,后经过的车站的编号 必须比 先经过的车站的编号 大。

求出在 T 分钟内,可抵达车站的最大数目。

输入:

 第一行有三个整数 N,M,K,用空格分隔。
第二行有三个整数 A,B,C,用空格分隔。
第三行有一个整数 T
在接下来的 M 行中第 i行有一个整数 Si​​。
输入的所有数的含义见题目描述。

输出:

一行,一个整数,表示在 T 分钟内,可抵达车站的最大数目。

数据范围:

对于 18%的数据,N<=300,KM=2,A<=106,T<=109
对于另外 30%的数据,N<=300
对于所有数据,1<=N<=109,2<=M<=K<=3000,K,=N,1<=B<C<A<=109,1<=T<=1018​​, 1=S1<S2<<SM=N1=S1<S2<⋯<SM=N。

算法标签:贪心!

思路:

一开始可能会有诸多想法,看到数据范围,就大概知道诸多想法只剩贪心可行。关键条件B<C<A,因此我们可以贪心的找点,每次在两个快车站之间寻找加一辆准快车会变得可行的车站数,加入一个堆中,因为可能出现一个车站增加的可行方案数量不同。

搜这道题位于top1的博主写得特别好阿炒鸡清晰!本蒟蒻也是看了题解才懂得的

以下代码:

#include<bits/stdc++.h>
#define il inline
#define LL long long
#define _(d) while(d(isdigit(ch=getchar())))
using namespace std;
const int N=3005;int n,m,k,s[N],ans,tot,q[N*N];LL A,B,C,T;
il LL read(){LL x;char ch;_(!);x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return x;}
il int gets(int l,int r){
    int res=0,now=l;LL t=B*l;int num=0;
    while(now<r&&T-t>=0){
        LL x=T-t;x/=A;LL nxt=now+x+1;
        nxt=min((LL)r,nxt);
        if(now==l)res=nxt-now;
        else q[++tot]=nxt-now;
        t+=C*(nxt-now);now=nxt;num++;
        if(num>k-m)break;
    }
    return res;
}
int main()
{
    n=(int)read();m=(int)read();k=(int)read();
    A=read();B=read();C=read();T=read();
    for(int i=1;i<=m;i++)s[i]=(int)read()-1;
    for(int i=1;i<m;i++)ans+=gets(s[i],s[i+1]);
    sort(q+1,q+1+tot);reverse(q+1,q+1+tot);
    for(int i=1;i<=k-m;i++)ans+=q[i];
    if(B*s[m]<=T);else ans--;
    printf("%d\n",ans);
  return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/Jessie-/p/9874639.html
今日推荐