题目回顾
问题描述
小明想从A徒步到B,总路程需要M天,路程中为了确保安全,小明每天需要消耗1份食物。
在起点及路程当中,零星分布着N个补给站,可以补充食物,不同补给站的食物价格可能不同。
请问小明若要安全完成徒步,最少需要花费多少钱呢?
输入格式
第一行为两个正整数M、N,代表总路程M天,补给站个数N
接下来N行,每行有两个非负整数A、B代表一个补给站,表示第A天经过该补给站,每份食物的价格为B元。
A是从0开始严格递增的,即起点一定有补给站,补给站是按位置顺序给出的,且同一个位置最多有一个补给站。
输出格式
输出一个整数,表示最少花费的金额
输入样例
5 4
0 2
1 3
2 1
3 2
输出样例
7
说明:在第0天买2份食物,在第2天买3份食物,共花费7元
数据范围
- 30%的数据,
N <= M <= 100,0 <= A < M,0 <= B <= 1000 - 80%的数据,
N <= M <= 10000,0 <= A < M,0 <= B <= 1000 - 100%的数据,
N <= M <= 1000000,0 <= A < M,0 <= B <= 1000
解题思路:使用背包算法依次记录第n天的最小花费。
首先我们要思考,当天能买到最便宜的补给在哪里?在当天之前经过的i个补给站里,存在最便宜的补给。所以,我们需要一个变量mina记录当前可以买到的最便宜的补给。//这里不使用min是为了防止和标准库中的min()撞定义。
然后,我们需要思考当天的花费最小值是由什么构成,是由当天之前能买到的最便宜的补给的价格加上前一天需要花费的价格组成。设第i天的花费为a[i]则有如下式子:
a[i] = a[i-1]+mina;
所以,我们需要一个记录当前天数的数组,这里我们使用vector
当然,直接开int数组也是可以解的,但要注意数据范围防止越界。
值得注意的是,在第一天时,若i=0,则i-1=-1,此时会引发数组越界,为了方便,我们从1开始记录数组。于是,就有了如下代码:
` #include #include #define ll long long using namespace std; int solution(int m, int n, std::vector<std::vector> p) { // Edit your code here vector a(m + 1, 0); int mina = 1000000, s = 0; for (int i = 1; i <= m; i++) { if (s < n) { if (i - 1 == p[s][0]) { if (mina > p[s][1]) mina = p[s][1]; s++; } } a[i] = a[i - 1] + mina; } return a[m]; }
int main() { // Add your test cases here std::cout << (solution(5, 4, {{0, 2}, {1, 3}, {2, 1}, {3, 2}}) == 7); return 0; } `