题目来自洛谷-P9749,传送门
题目描述
小苞准备开着车沿着公路自驾。
公路上一共有 n n n 个站点,编号为从 1 1 1 到 n n n。其中站点 i i i 与站点 i + 1 i + 1 i+1 的距离为 v i v_i vi 公里。
公路上每个站点都可以加油,编号为 i i i 的站点一升油的价格为 a i a_i ai 元,且每个站点只出售整数升的油。
小苞想从站点 1 1 1 开车到站点 n n n,一开始小苞在站点 1 1 1 且车的油箱是空的。已知车的油箱足够大,可以装下任意多的油,且每升油可以让车前进 d d d 公里。问小苞从站点 1 1 1 开到站点 n n n,至少要花多少钱加油?
输入格式
输入的第一行包含两个正整数 n n n 和 d d d,分别表示公路上站点的数量和车每升油可以前进的距离。
输入的第二行包含 n − 1 n - 1 n−1 个正整数 v 1 , v 2 … v n − 1 v_1, v_2\dots v_{n-1} v1,v2…vn−1,分别表示站点间的距离。
输入的第三行包含 n n n 个正整数 a 1 , a 2 … a n a_1, a_2 \dots a_n a1,a2…an,分别表示在不同站点加油的价格。
输出格式
输出一行,仅包含一个正整数,表示从站点 1 1 1 开到站点 n n n,小苞至少要花多少钱加油。
样例 #1
样例输入 #1
5 4
10 10 10 10
9 8 9 6 5
样例输出 #1
79
提示
【样例 1 解释】
最优方案下:小苞在站点 1 1 1 买了 3 3 3 升油,在站点 2 2 2 购买了 5 5 5 升油,在站点 4 4 4 购买了 2 2 2 升油。
【数据范围】
对于所有测试数据保证: 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1≤n≤105, 1 ≤ d ≤ 1 0 5 1 \leq d \leq 10^5 1≤d≤105, 1 ≤ v i ≤ 1 0 5 1 \leq v_i \leq 10^5 1≤vi≤105, 1 ≤ a i ≤ 1 0 5 1 \leq a_i \leq 10^5 1≤ai≤105。
原因分析:
提示:我先自己手动模拟了一下,假设我自己去加油,我会先在第1站加油开去第2站,第2站的油价比第3更便宜,但是比第4站的油价高,所以我就开两站去第4站,最后从第4站开到终点站第5段。总之就是哪站便宜我就加油,直到我看到更便宜的油价的加油站我才停下来。
(每次都加目前最便宜的油,体现贪心!)
解决方案:
提示:代码注释写的比较详细,方便自己下次能看懂
```cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long int n,d,cnt,minn,weizhi=0,ans=0;//cnt表示每次加的几升油,minn是取最少的油价 ,每一站都要对比的
cin>>n>>d;//weizhi表示,我目前的油还能走到的下一段还剩的距离,比如买了3升油可以走12公里,但是到下一站只需要10,所以weizhi=12-10=2
long long int dis[100005],oil[100005];
for(int i=1;i<=n-1;i++)
cin>>dis[i];
for(int i=1;i<=n;i++)
cin>>oil[i];
minn=oil[1];//不管贵不贵,肯定要从站1开始走
for(int i=1;i<=n-1;i++) //总共是n-1段路,要算账n-1次
{
//cnt=ceil((dis[i]-weizhi)*1.0/d);
if(i==1)//第一个站 特判一下
{
ans+=ceil((dis[i]-weizhi)*1.0/d)*oil[i];
cnt=ceil((dis[i]-weizhi)*1.0/d);//ceil是向上取整的意思
}
else//i>=2
{
if(oil[i]<minn)//这站的油价比上一站(不止上一站,是比我最便宜的油价)还便宜,那更新minn,在这一站买
{
minn=oil[i];
cnt=ceil((dis[i]-weizhi)*1.0/d);
ans=ans+cnt*minn;//几升油*油价 =总钱
}
else//这站的油价比我之前的油价更贵,那就不在这一站买,在我最便宜的时候多买一站--由结果来推导我之前的决定。
//就是说,比如我这站贵,那我就在上一站多买一站 ,如果下一站还是比我Minn贵,我就继续买 ,直到比我minn更小的时候才停下来加油
{
cnt=ceil((dis[i]-weizhi)*1.0/d);
ans=ans+cnt*minn;//这里的minn没有更新,还是用的原来的便宜油价
}
}
weizhi=cnt*d-(dis[i]-weizhi);//每一站都要更新weizhi !
}
cout<<ans;
return 0;
}
如果有问题可以在评论区指出~