JOI 铁路公司是 JOI 国唯一的铁路公司。
在某条铁路沿线共有 N 座车站,依次编号为 1...N 。目前,正在服役的车次按照运行速度可分为两类:高速电车(简称快车)与普通电车(简称慢车)。
- 慢车每站都停。乘慢车时,对于任意一座车站 i(1<= i<N) ,车站 i 到车站 i+1 用时均为 A 。
- 快车只在车站 S1,S2,…,SM 停车 (1=S1<S2<⋯<SM=N) 。乘快车时,对于任意一座车站 i(1<=i<N) ,车站 i 到车站 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,K−M=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 ",ans); return 0; }