4471: 公路 [CSP-J 2023]
内存限制:512 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:6
解决:3
题目描述
小苞准备开着车沿着公路自驾。
公路上一共有 个站点,编号为从 到 。其中站点 与站点 的距离为 公里。
公路上每个站点都可以加油,编号为 的站点一升油的价格为 元,且每个站点只出售整数升的油。
小苞想从站点 开车到站点 ,一开始小苞在站点 且车的油箱是空的。已知车的油箱足够大,可以装下任意多的油,且每升油可以让车前进 公里。问小苞从站点 开到站点 ,至少要花多少钱加油?
输入
输入的第一行包含两个正整数 和 ,分别表示公路上站点的数量和车每升油可以前进的距离。
输入的第二行包含 个正整数 ,分别表示站点间的距离。
输入的第三行包含 个正整数 ,分别表示在不同站点加油的价格。
输出
输出一行,仅包含一个正整数,表示从站点 开到站点 ,小苞至少要花多少钱加油。
样例输入 复制
5 4
10 10 10 10
9 8 9 6 5
样例输出 复制
79
提示
【样例 1 解释】
最优方案下:小苞在站点 买了 升油,在站点 购买了 升油,在站点 购买了 升油。
【样例 2】
见选手目录下的 road/road2.in 与 road/road2.ans。
【数据范围】
对于所有测试数据保证:,,,。
| 测试点 | 特殊性质 | |
|---|---|---|
| 无 | ||
| 无 | ||
| A | ||
| B | ||
| 无 |
- 特殊性质 A:站点 的油价最低。
- 特殊性质 B:对于所有 , 为 的倍数。
#include<bits/stdc++.h>
using namespace std;
/*解法:贪心+模拟-时间复杂度-O(n)-100pts*/
const long long N = 1e5 + 10;
long long s[N];//距离的前缀和数组-用于求解任意两点间的距离
long long p[N];//每个站点对应的油价price
int main() {
long long n, d; cin >> n >> d;
for (long long i = 2; i <= n; i++) {
long long v; cin >> v;
s[i] = s[i - 1] + v;//预处理距离的前缀和
}
for (long long i = 1; i <= n; i++) cin >> p[i];
//处理油价的降序序列
vector<long long> ds; ds.push_back(1);
long long minv = p[1];
for (long long i = 2; i <= n; i++) {
if (p[i] < minv) {
minv = p[i];
ds.push_back(i);
}
}
if (ds[ds.size() - 1] != n) ds.push_back(n);
long long l_dist = 0/*剩余距离*/, ans = 0;
//沿着油价的降序序列进行贪心+模拟
for (long long i=0; i < ds.size() - 1; i++) {
long long r_dist = s[ds[i + 1]] - s[ds[i]];//相邻两点间的距离
if (r_dist < l_dist) l_dist -= r_dist;
else {
r_dist -= l_dist;
long long nums = ceil(r_dist * 1.0 / d);//针对当前距离需要买多少升油
ans += p[ds[i]] * nums;
l_dist = nums * d - r_dist;
}
}
cout << ans << endl;
return 0;
}