Meaning
给定 n,dn,d,表示有 nn 个站点,每升油可以使汽车前进 dd 公里,每两个相邻的站点间的距离是 vivi,每个站点的油价是 aiai,问从站点 11 开车到站点 nn 至少要花多少钱(油箱一开始是空的)。
Solution
可以发现站点 11 到站点 22 的油一定要在站点 11 购买,站点 22 到站点 33 的油可以在站点 11 和站点 22 购买,后面的以此类推。
所以就是从站点 ii 到站点 i+1i+1 的油可以在前 ii 个站点购买,就相当于购买从站点 ii 到站点 i+1i+1 的油的钱数就是前 ii 个站点买油需要的最小值。
知道了这个,就可以模拟了。
对于每个站点 ii:
- 如果它是目前油价最低的站点,那么就在这个站点买油。
- 反之就要在目前油价最低的站点购买。
定义目前油价最低的站点的油价为 ww,上一次剩余的油量为 kk,从站点 ii 到站点 i+1i+1 买油需要的钱数为:w×⌈vi−kd⌉w×⌈dvi−k⌉,下一步的 kk 为:⌈vi−kd⌉×d−(vi−k)⌈dvi−k⌉×d−(vi−k)。
Accept Code
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;
int n, d, v[MAXN], a[MAXN];
int main() {
// freopen("road.in", "r", stdin);
// freopen("road.out", "w", stdout);
cin >> n >> d;
for (int i = 1; i < n; i++) {
cin >> v[i];
}
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int mi = a[1];
int sum = 0;
long long ans = 0;
for (int i = 1; i <= n; i++) {
mi = min(mi, a[i]);
if (sum >= v[i]) {
sum -= v[i];
continue;
}
int t = (v[i] - sum + d - 1) / d;
ans += 1ll * t * mi;
sum = t * d + sum - v[i];
}
cout << ans;
return 0;
}
18