一、题目
二、解法
首先对于每一个位置,它的路径一定是 快车->
准快车->
慢车,三段都可以为空。
考虑把所有位置按照快车站的位置划分成若干段,对于每一段,我们先算出坐慢车最多到哪里,然后在下一个位置贪心地放一个准快车站,在算出从这个准快车站坐慢车的最远到达位置,然后重复上面的过程…
选贡献最大地方放车站即可,对于每一个段我们只需要取最大的前 k − m k-m k−m个,所以时间复杂度 O ( k m ) O(km) O(km),具体实现我是把快车站单独讨论了,有些细节讲不清楚请看代码。
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
const int M = 3005;
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int n,m,k,a,b,c,t,s[M],ans;
vector<int> g;
signed main()
{
n=read();m=read();k=read();
a=read();b=read();c=read();
t=read();
for(int i=1;i<=m;i++)
s[i]=read();
for(int i=2;i<=m;i++)
{
int t1=(s[i-1]-1)*b;
if(t1>t) break;
int d=(t-t1)/a;
ans+=min(s[i]-s[i-1]-1,d);
if(d>=s[i]-s[i-1]) continue;
int l=s[i-1]+min(s[i]-s[i-1]-1,(t-t1)/c),times=0;
for(int j=s[i-1]+d+1;j<=l;)
{
int tmp=(t-t1-(j-s[i-1])*c)/a;
tmp=min(tmp,s[i]-j-1);
g.push_back(tmp+1);
j=j+tmp+1;
times++;
if(times+m>=k) break;
}
}
for(int i=2;i<=m;i++)
if((s[i]-1)*b<=t)
ans++;
if(g.size()==0) goto In;
sort(g.begin(),g.end());
for(int i=g.size()-1;i>=0;i--)
if(k>m)
{
k--;
ans+=g[i];
}
In:;
printf("%lld\n",ans);
}