补给站最优花费问题 | 豆包MarsCode AI刷题

61 阅读3分钟

1. 问题描述:****

小明需要从起点A徒步到终点B,总路程需要M天,每天需要消耗1份食物。在路程中,有N个补给站可以补充食物,不同补给站的食物价格可能不同。我们需要找到一种策略,使得小明在完成徒步的过程中花费最少的钱。

 

第一行为两个正整数M、N,代表总路程M天,补给站个数N

接下来N行,每行有两个非负整数A、B代表一个补给站,表示第A天经过该补给站,每份食物的价格为B元。A是从0开始严格递增的,即起点一定有补给站,补给站是按位置顺序给出的,且同一个位置最多有个补给站。

 

2. 输出格式****

 

输出一个整数,表示最少花费的金额

 

3. 输入样例

5 4

 

4. 输出样例****

7

 

说明: 在第0天买2份食物,在第2天买3份食物,共花费7元

 

5. 数据范围****

30%的数据,N <= M <= 109, <= A< M, <= B <= 1009

80%的数据,N <= M <= 10009, <= A< M, <= B <= 1800

100%的数据,N <= M <= 1090008, <= A< M, <= B <= 1080

 

6. 解题思路:****

 

[1] 问题理解****

小明需要从起点A徒步到终点B,总路程需要M天,每天需要消耗1份食物。在路程中,有N个补给站可以补充食物,不同补给站的食物价格可能不同。我们需要找到一种策略,使得小明在完成徒步的过程中花费最少的钱。

 

[2] 数据结构选择****

(1)补给站信息:我们可以使用一个数组来存储补给站的信息,每个补给站包含两个整数:天数A和价格B。

(2)最小花费:我们可以使用一个数组minCost来记录从第0天到第i天的最小花费。

[3] 算法步骤****

(1)初始化:从起点开始,初始化最小花费数组minCost,minCost[0]为0,表示第0天的最小花费为0。

(2)动态规划:

对于每一天i,我们需要找到前一天的最小花费,并加上当前天的食物价格。

如果当前天有补给站,则更新当前天的最小花费。

如果没有补给站,则当前天的最小花费等于前一天的最小花费。

结果:最终的最小花费就是minCost[M-1],即第M-1天的最小花费。

7. 最终代码:  

#include

#include

#include <limits.h>

 

int caculate(const std::vector<std::vector>& p, int j) {

    // 搜索当前的最小的价格对应的索引, j为迭代的上界

    int result = 0;

    int min = p[0][1];

 

    for (int i = 0; i < j; i++) {

        if (p[i][1] < min) {

            min = p[i][1];

            result = i;

        }

    }

 

    return result;

}

 

int get(int cost, int m, const std::vector<std::vector>& p, int d) {

    // m记录剩余的路程的天数,d记录当前的数组的上界

    // 递归的出口

    if (d <= 0) return cost;

 

    int j = caculate(p, d);

    int minPrice = p[j][1];

    cost = cost + minPrice * (m - p[j][0]);

    int days = p[j][0];

    return get(cost, days, p, j);

}

 

int solution(int m, int n, const std::vector<std::vector>& p) {

    /*

     * 每次把路程分为两段,找到最便宜的补给站之前,和之后

     * 可以通过递归的方法实现,同时使用了贪心的思想

     */

    int cost = get(0, m, p, n);

    // std::cout << cost << std::endl;

    return cost;

}

 

int main() {

    // Add your test cases here

    std::cout << (solution(5, 4, {{0, 2}, {1, 3}, {2, 1}, {3, 2}}) == 7) << std::endl;

    

    return 0;

}