洛谷P9749 [CSP-J 2023] 公路 题解
本题做法
- 前缀和思想、模拟和贪心。
思路
定义一个数组 \(pre[i]\) 表示油价数组 \(a\) 中 \(a[1]\sim a[i]\) 中的最小油价,递推公式为 \(pre[i]=\min\{pre[i-1], a[i]\}(i>1),pre[1]=a[1]\)。遍历距离数组 \(v\) 的 \(1\sim n-1\)(因为第 \(n\) 站没有后续站点了),每次算出需要购买的油量(注意:这里有坑!需要使用 double 存储上一次加油剩下的油量,详见样例 1 的第二站。且油量需要向上取整。)乘上 \(pre[i]\),所有的乘积相加得到结果。公式就是
\[\sum_{i=1}^{n-1}{pre[i]\times ⌈v[i]\div d-s⌉(其中s为剩余的油量,计算公式为s=⌈v[i]\div d-s⌉+s-v[i]\div d)}
\]
代码
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const double EPS=1e-8;
const int N=1e5+5;
long long n,d,p,v[N],pre[N],a[N];
long double s;
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin>>n>>d;
for(int i=1;i<n;i++) cin>>v[i];
for(int i=1;i<=n;i++) {
cin>>a[i];
if(i==1) pre[i]=a[i];
else pre[i]=min(pre[i-1],a[i]);
}
for(int i=1;i<n;i++){
p+=ceil(1.0*v[i]/d-s)*pre[i];
s=ceil(1.0*v[i]/d-s)+s-1.0*v[i]/d;
}
cout<<p;
return 0;
}

浙公网安备 33010602011771号