P9749 [CSP-J 2023] 公路

题目描述

小苞准备开着车沿着公路自驾。

公路上一共有n个站点,编号为从1到n。其中站点i与站点i+1的距离为vi​公里。

公路上每个站点都可以加油,编号为i的站点一升油的价格为ai元,且每个站点只出售整数升的油。

小苞想从站点1开车到站点n,一开始小苞在站点1且车的油箱是空的。已知车的油箱足够大,可以装下任意多的油,且每升油可以让车前进d 公里。问小苞从站点1开到站点n,至少要花多少钱加油?

输入格式

输入的第一行包含两个正整数n和d,分别表示公路上站点的数量和车每升油可以前进的距离。

输入的第二行包含n−1个正整数v1​,v2​…vn−1​,分别表示站点间的距离。

输入的第三行包含n个正整数a1​,a2​…an​,分别表示在不同站点加油的价格。

输出格式

输出一行,仅包含一个正整数,表示从站点1开到站点 n,小苞至少要花多少钱加油。

输入输出样例

输入 #1

5 4
10 10 10 10
9 8 9 6 5

输出 #1

79

说明/提示

【样例 1 解释】

最优方案下:小苞在站点1买了3升油,在站点2购买了5升油,在站点4购买了2升油。

【样例 2】

见选手目录下的 road/road2.in 与 road/road2.ans。

P9749 [CSP-J 2023] 公路_第1张图片

题解:

考虑贪心,首先站点1必须加油否则根本动不了,贪心思路:在一个加油站加从此加油站到在它后面第一个比他便宜的加油站即可。

那么我们可以维护一个前缀最小值minn保存从1到i加油站最便宜的油的价格。每次枚举i,代表当前是要从i号走到i+1号,接着再用之前的贪心策略模拟即可。

【AC代码】

#include
using namespace std;
long long a[100005], v[100005], ans = 0, pos = 0;
long long cnt = 0;
int main(){

	long long n, d;
    cin >> n >> d;
	for(int i = 1; i <= n - 1; i++)cin >> v[i];
	for(int i = 1; i <= n; i++) cin >> a[i];
	long long minn = a[1];
	for(int i = 1; i <= n - 1; i++)
	{
		cnt = ceil((v[i] - pos) * 1.0 / d);
		if(i == 1) ans += cnt * minn;
		else
		{         
			if(a[i] < minn)
			{ 
				minn = a[i];
				ans += ceil((v[i] - pos) * 1.0 / d) * minn;
				cnt = ceil((v[i] - pos) * 1.0 / d);
			}
			else
			{
				ans += ceil((v[i] - pos) * 1.0 / d) * minn;
				cnt = ceil((v[i] - pos) * 1.0 / d);
			}
		}
		pos = cnt * d - (v[i] - pos);
	}
    cout << ans;
	return 0;
}

你可能感兴趣的:(算法,前端)