[CSP-J 2023] 公路

· · 题解

[CSP-J 2023] 公路【民间数据】

题目描述

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

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

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

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

输入格式

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

输入的第二行包含 n - 1 个正整数 v_1, v_2\dots v_{n-1},分别表示站点间的距离。

输入的第三行包含 n 个正整数 a_1, a_2 \dots a_n,分别表示在不同站点加油的价格。

输出格式

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

样例 #1

样例输入 #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。

【数据范围】

对于所有测试数据保证:1 \leq n \leq 10^51 \leq d \leq 10^51 \leq v_i \leq 10^51 \leq a_i \leq 10^5

测试点 n \leq 特殊性质
1\sim 5 8
6\sim 10 10^3
11\sim 13 10^5 A
14\sim 16 10^5 B
17\sim 20 10^5

思路:

题目让我们求的是买油用的最少的钱 ( 且要到达终点 ) ,而且已知车的速度一直都不变,那么我们就得使每次的油价最小,所以就应该用到贪心。

首先我们要将从起点到第 i ( 2 \le i \le n ) 个点所需的油记录在 w[ i ] 中 ( 向上取整 ) ,然后循环每一次油价,记录下最小的油价 x,使每一次能用之前最小的油价,然后再用一个变量 ans 累加上 w[ i ] 乘上 x 的积 ( 也就是从 i-1i 买油所用的钱 ) ,最后输出 ans 就可以了。

代码如下:

#include<bits/stdc++.h>
#define int long long

using namespace std;

int n,m,x = 0x7fffffff,ans;
int c[1000005]; //储存距离
int v; //储存油价
int w[1000005]; //储存从第起点到底 i 个点所需几升油

signed main(){

    ios::sync_with_stdio(0); //输入输出优化
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m; //输入
    for(int i=1;i<n;i++){
        cin >> c[i];
        c[i] += c[i-1]; //用前缀和记录路程
        if(c[i] % m != 0){ //向上取整
            w[i]++;
        }
        w[i] += c[i] / m; //记录油量
    }
    for(int i=1;i<=n;i++){
        cin >> v;
        x = min(x,v); //贪心,使每次能用之前最小的油价
        ans += (w[i] - w[i-1]) * x; //累加每次用的钱
    }
    cout << ans; //输出

    return 0;
}