题目描述

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

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

  • 慢车每站都停。乘慢车时,对于任意一座车站 $i(1⩽i<N)$,车站 $i$ 到车站$ i+1$ 用时均为 $A$。
  • 快车只在车站 $S_1, S_2, \ldots, S_M$​​ 停车 $(1=S_1<S_2<\cdots<S_M=N)$。乘快车时,对于任意一座车站 $i(1\leqslant i<N)$,车站 $i$ 到车站 $i+1$ 用时均为 $B$。

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

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

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

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

输入格式

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

输出格式

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

样例

样例输入 1

10 3 5
10 3 5
30
1
6
10

样例输出 1

8

样例解释 1

在这组样例中,这条铁路上有 $10$ 个车站,快车在车站 $1, 6, 10$ 停车。如果准快车在车站 $1, 5, 6, 8, 10$ 停车,除车站⑨外的其它所有车站都可在 $30$ 分钟内到达。
以下是从地点 $1$ 到达某些站点的最快方案:

  • 到达车站 $3$:乘坐慢车,耗时 $20$ 分钟。
  • 到达车站 $7$:先乘坐快车,在车站 $6$ 转慢车,耗时 $25$ 分钟。
  • 到达车站 $8$:先乘坐快车,在车站 $6$ 转准快车,耗时 $25$ 分钟。
  • 到达车站⑨:先乘坐快车,在车站 $6$ 转准快车,在车站 $8$ 再转慢车,耗时 $35$ 分钟。

样例输入 2

10 3 5
10 3 5
25
1
6
10

样例输出 2

7

样例输入 3

90 10 12
100000 1000 10000
10000
1
10
20
30
40
50
60
70
80
90

样例输出 3

2

样例输入 4

12 3 4
10 1 2
30
1
11
12

样例输出 4

8

样例输入 5

300 8 16
345678901 123456789 234567890
12345678901
1
10
77
82
137
210
297
300

样例输出 5

72

样例输入 6

1000000000 2 3000
1000000000 1 2
1000000000
1
1000000000

样例输出 6

3000

数据范围与提示

对于 $18\%$的数据,$N\leqslant 300, K-M=2, A\leqslant 10^6, T\leqslant 10^9$。
对于另外 $30\%$ 的数据,$N\leqslant 300$。
对于所有数据,$1\leqslant N\leqslant 10^9, 2\leqslant M\leqslant K\leqslant 3000, K\leqslant N, 1\leqslant B<C<A\leqslant 10^9, 1\leqslant T\leqslant 10^{18}$​​, $1=S_1<S_2<\cdots<S_M=N$。

一开始只想了48tps的dp:设dp[i][j][k]表示到达第i个车站,已经新开了j个准快车停车站,且接下来准备换成 慢车(0)/快车(1)/准快车(2)时所需要的时间,最后判断满足$min\{dp[i][k-m][0], dp[i][k-m][1], dp[i][k-m][2]\} \leq T$ $|$ $2<=i<=n$的站数即可(即计算从起点到每个车站的最短时间)。

然而这个dp显然是错误的,原因是这样没有统一确定准快车的停车站;而且在当前点没有车站/准车站时,最后计算到达当前车站的最短距离时,如果当前车站不是快车/准快车的停车站时,对应的dp项是不能放入min的,因为这一站不停。(不如直接说读错题了)

那怎么做呢?直觉告诉我们$n=10^9$这样的数据不能dp,也不能常规循环,看来一定要在区间上动手。

这就可以想到贪心了。

既然要贪心,就得考虑增设哪些停车站停准快车,以及每个增设的停车站能让多大的车站区间在要求时间T内被到达。

很显然,对于每个能增设的停车站,应该优先先选影响车站区间大的,即增设这个停车站 能让尽量多的车站能满足在要求时间T内被到达。

那哪些停车站是备选的?影响区间又有什么突破点?(来欣赏一下我一流的绘画技术)

上图的$s[i],s[i+1]$表示两个相邻的快车停车站。我们就在每两个快车停车站之间 找找选准快车停车站有没有什么好方法。

但是在明白之前你得注意到一个题目条件B<C<A。这种条件非常重要,它不是摆给你玩的,相反它打下了这题贪心的基础。没这个条件的话这题贪心估计没法做

这个条件的用处就是可以帮助你想到,从1号车站到达任意一个车站所需的最短时间是什么?

没错,既然有了上述条件,那肯定先尽可能坐快车,其次尽可能坐准快车,最后坐慢车到达目的地。

放到图上就是,从1号点出发,先坐快车到离终点最近的快车停车站(1号点到终点间没有快车停车站则不坐),再从这站坐准快车到离终点最近的准快车停车站(这站到终点间没有准快车停车站则不坐),最后从这站坐慢车到终点。

容易证明,这样就保证了能够优先坐速度快的车,那么到终点站的用时也最短。

明白了上述道理之后,就开始分析图了:

图中的黑色竖线表示两个相邻的快车停车站,橙色竖线表示非快车停车站(普通站),红色竖线表示需要考虑选到的准快车停车站

图中的绿色横线表示从前一个快车停车站开始坐慢车能在要求时间T内到达的车站区间,红色横线表示从左端需要考虑选到的准快车停车站开始坐慢车能在要求时间T内到达的车站区间。

很明显,在$(s[i],s[i+1])$这段开区间内,被绿色横线覆盖的车站 都可以通过从起点坐快车到快车停车站s[i] 再转慢车在规定时间内坐到。而没有覆盖到的车站就不行,需要另辟准快车停车站。

但不可能把所有车站都考虑辟为准快车停车站,那样时间复杂度就退化为至少$O(n)$,直接爆。

一定有一些辟车站的决策是无用的,比如某个车站被辟了之后,明显不如辟另一个车站更优,因此不能考虑。

所以哪里要考虑辟为准快车停车站?在前一个横线覆盖的区间后的一个点

为什么要放在这?

- 如果往前放,就放到前一个已经能够在时限内到达的车站区间了(简称已覆盖区间),可以证明重新覆盖这些车站是没有必要的,因为你希望让已覆盖区间后边的车站(它们还不能在时限内到达)能在时限内到达,那么准快车车站应该尽量靠近后边这些车站,这样就能在其它车站条件相同的情况下 坐更多站的准快车,用更短时间到达那些车站。所以准快车停车站一定会放在后边未覆盖的车站区间,而不应放在前边的已覆盖区间。

- 如果往后放,中间就会空出几个车站无法在时限内到达。但是中间这些空出的车站本身就具有 距离前一个快车停车站近的优势,如果坐同一种车(准快车),时间相对较短;相反,后边的车站无论如何都要比这些空出的车站多坐几站准快车,那时间就相对较长,转坐慢车会相对更快达到时限,导致在后边放准快车停车站所能覆盖的区间更短(一定要想清楚)。我们希望一个准快车停车站的覆盖区间尽量大,因此根据数学归纳法(其实不用说的这么高端),把准快车停车站放到第一个覆盖不到的车站,再往后转坐慢车时会相对更慢地到达时限,覆盖的区间也就极大,即最优放法。

上面从左右两个角度论证了在前一个横线覆盖的区间后的一个点辟准快车停车站是最优的。

所以上图就在相邻两个快车停车站区间内 从左往右依次在第一个覆盖不到的点记为需要考虑选到的准快车停车站,然后将 它能覆盖 且 能对车站产生最优答案(到达时间) 的区间大小记为贡献

- 有没有注意到,上图中准快车停车站所覆盖的区间大小从左往右是单调不上升的

确实是这么个结论,由前面说的“如果准快车停车站往右放”一段的论证可以推广证明。

- 另外,注意到最后一条红线被一些紫线划去了没有?

最后一个需要考虑的准快车停车站 所覆盖的区间 需要特判,要将它的右端点控制在快车停车站s[i+1]之前,不能计算从s[i+1]开始的贡献。因为根据前面推的先尽可能坐快车,其次尽可能坐准快车,最后坐慢车到达目的地这个结论,s[i+1]及之后的车站可以通过从起点直接坐到快车停车站s[i+1]来更快到达,前面考虑的准快车停车站无法对它们产生更优的答案(到达时间),因此不能算作贡献这就是为什么前面没有直接说“准快车停车站能覆盖的区间大小就是贡献”

以上结论适用于任意两个相邻的快车停车站之间。

也就是说,在每两个相邻的快车停车站之间,候选准快车停车站所产生的贡献都是单调不上升的。

那么简化问题,如果只考虑两个相邻的快车停车站区间,从左往右依次取需要考虑选到的准快车停车站,贡献就是从大到小取的了,那么答案也就最优。

然而多个具有这种性质的相邻快车停车站区间咋办?

统一从左往右取。就是把每个这样的区间中的第一个需要考虑选到的准快车停车站放入一个优先队列,每次取贡献最大的那个停车站,并把这个停车站所在的相邻快车停车站区间的 下一个要考虑的停车站 放入优先队列 即可。

 #include<cstdio>
#include<vector>
#include<algorithm> using namespace std; const int MAX_M = ; int N, M, K;
long long A, B, C;
long long T;
int s[MAX_M]; int nums[ * ];
int c = ; int getNums(int l, int r){
int res = ;
long long t = B * l;
int id = l;
int cnt = ;
while(id < r){
long long x = T - t;
if(x < ) break;
x /= A;
long long nxt = id + x + ;
nxt = min((long long)r, nxt);
if(id == l) res = nxt - id;
else nums[c++] = nxt - id;
t += C * (nxt - id);
id = nxt;
cnt++;
if(cnt > K - M) break;
}
return res;
} int solve(){
int ans = B * s[M - ] <= T ? : ;
for(int i = ; i < M - ; ++i){
ans += getNums(s[i], s[i + ]);
}
sort(nums, nums + c);
reverse(nums, nums + c);
for(int i = ; i < K - M; ++i){
ans += nums[i];
}
return ans - ;
} void input(){
scanf("%d%d%d", &N, &M, &K);
scanf("%lld%lld%lld", &A, &B, &C);
scanf("%lld", &T);
for(int i = ; i < M; ++i){
scanf("%d", s + i);
s[i]--;
}
} int main(){
input();
int ans = solve();
printf("%d\n", ans);
return ;
}

【2018.9.20】JOI 2017 Final T2「準急電車 / Semiexpress」的更多相关文章

  1. 【2018.9.20】JOI 2017 Final T3「JOIOI 王国 / The Kingdom of JOIOI」

    题目链接 题目描述 JOIOI 王国是一个 $H$ 行 $W$ 列的长方形网格,每个 $1\times 1$ 的子网格都是一个正方形的小区块.为了提高管理效率,我们决定把整个国家划分成两个省 $JOI ...

  2. 「JOI 2017 Final」JOIOI 王国

    「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...

  3. Libre OJ P2332「JOI 2017 Final」焚风现象【差分思想】By cellur925

    题目传送门 这道题开始看起来会很晕...\(qwq\).首先我们要明确题目中的海拔&&温度.温度是受海拔影响的,每次改变的是海拔,我们求的是温度. 我们开始读入的时候便可以处理出开始\ ...

  4. loj 2336「JOI 2017 Final」绳

    loj 首先,所有位置最多被染色一次,因为要染多次的话,还不如一开始就染成最终的颜色.并且你可以一开始就染好色 因为最终长度为2,那么如果染完后这个序列可以被折完,那么首先最多只有两种颜色,还有就是要 ...

  5. loj#2334 「JOI 2017 Final」JOIOI 王国

    分析 二分答案 判断左上角是否满足 为了覆盖所有范围 我们依次把右下角,左上角,右上角移动到左上角 代码 #include<bits/stdc++.h> using namespace s ...

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

    分析 我们发现到达一个点一定是先快车再准快车再慢车 于是快车将1-n分为多个区间 每次取出每个区间当前能到达的点的数量 选剩余时间贡献最大的的一个取得贡献并且再能到达的最远点建立准快车 代码 #inc ...

  7. loj#2332 「JOI 2017 Final」焚风现象

    分析 我们发现改变一个区间实际上只有两个端点的贡献变换 代码 #include<bits/stdc++.h> using namespace std; #define int long l ...

  8. 「JOI 2017 Final」绳

    题意 loj 做法 首先我们观察到最后能折起来的充要条件是: 只有两个颜色,除首尾外,所有颜色块内的数量为偶数 因为为偶数,我们进一步推论: 所有颜色块起始位置奇偶性相同 然后因为增与减都会有相同花费 ...

  9. [JOI 2017 Final] 足球 (建图,最短路)

    题面 题解 我们可以总结出球的两种状态,要么自己飞,要么在球员脚下被带飞. 自己飞的情况下,他只能单向直线运动,每一步代价为A,被带飞可以乱走,每一步代价为C. 从自己飞到被带飞需要一个距离自己最近的 ...

随机推荐

  1. vertx从入门到精通

    1.Vert.x安装指南 http://blog.csdn.net/sdyy321/article/details/38926005 http://blog.csdn.net/chszs/articl ...

  2. Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.Reason: Failed to determine a suitable driver class

    解决方案: @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 作用://取消数据库配置 但是 在用到数据库的时候记 ...

  3. 原生js格式化json的方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. HTTP协议重定向

    HTTP重定向:服务器无法处理浏览器发送过来的请求(request),服务器告诉浏览器跳转到可以处理请求的url上.(浏览器会自动访问该URL地址,以至于用户无法分辨是否重定向了.) 重定向的返回码3 ...

  5. KVM 重命名虚机

    KVM 重命名虚机 1. 查看虚机列表 [root@bjape01-kvm1 ~]# virsh  list --all Id    名称                         状态 --- ...

  6. java在线聊天项目 swt可视化窗口Design 好友列表窗口

    熟练使用各种布局方式 FlowLayout 流布局 left center right等 BorderLayout 边框布局 east west sorth north center Absolute ...

  7. vue 点击倒计时 ajax 封装

    方法:function(){ var that = this; if (that.time == 0) { that.disabled = false; that.text ="点击获取&q ...

  8. vba练习资料

    链接:https://pan.baidu.com/s/1E0e58rZ_3QCCorWNM-ehSA 提取码:jluf

  9. RN调试

    https://facebook.github.io/react-native/docs/debugging.html 热加载 RN的目标是极致的开发体验,修改文件后能在1秒内看到变化,通过以下三个特 ...

  10. 气泡小角的css实现

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr"> ...