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;
}