问题描述
小U计划进行一场从地点A到地点B的徒步旅行,旅行总共需要 M 天。为了在旅途中确保安全,小U每天都需要消耗一份食物。在路程中,小U会经过一些补给站,这些补给站分布在不同的天数上,且每个补给站的食物价格各不相同。
小U需要在这些补给站中购买食物,以确保每天都有足够的食物。现在她想知道,如何规划在不同补给站的购买策略,以使她能够花费最少的钱顺利完成这次旅行。
M:总路程所需的天数。N:路上补给站的数量。p:每个补给站的描述,包含两个数字A和B,表示第A天有一个补给站,并且该站每份食物的价格为B元。
保证第0天一定有一个补给站,并且补给站是按顺序出现的。
测试样例
样例1:
输入:
m = 5 ,n = 4 ,p = [[0, 2], [1, 3], [2, 1], [3, 2]]
输出:7
题目解析
这是一道动态规划问题,核心是最优子结构的构建与状态转移。题目要求小U在徒步旅行中花费最少的钱购买食物,需要我们设计一个算法来规划购买策略。以下是详细分析和解答步骤。
解题思路
-
状态定义
用一个数组dp[i]表示到第i天为止的最小花费。 -
状态转移方程
- 从一个补给站到另一天,可以根据补给站的食物价格和需要购买的天数计算花费: dp[i]=min(dp[i],dp[day]+(i−day)×price)dp[i] = \min(dp[i], dp[day] + (i - day) \times price)dp[i]=min(dp[i],dp[day]+(i−day)×price)
其中:
day是补给站所在的天数。price是该补给站的食物单价。- 状态转移的核心是考虑从某个补给站出发,购买足够的食物以支撑到当前天
i,并比较多种选择后的最小花费。
-
初始化
- 第 0 天
dp[0] = 0,因为初始花费为 0。 - 其余天数的
dp初始化为正无穷大,表示初始状态下无法到达。
- 第 0 天
-
遍历顺序
- 外层循环遍历每一天
i。 - 内层循环遍历所有补给站,更新当天的最小花费。
- 外层循环遍历每一天
-
结果
- 最终返回
dp[m]即为完成所有天数所需的最小花费。 -
时间复杂度与优化
- 最终返回
-
时间复杂度
- 外层遍历天数
O(M)。 - 内层遍历补给站
O(N)。 - 总复杂度:
O(M * N)。
- 外层遍历天数
-
空间复杂度
- 使用了一维数组
dp:O(M)。
- 使用了一维数组
-
优化思路
- 可使用滑动窗口优化
dp更新,减少不必要的重复计算。
- 可使用滑动窗口优化
总结
- 动态规划的核心是找到最优子结构并构建状态转移公式。
- 本题通过二维数组的遍历和对状态的合理初始化,成功实现了从起点到终点的最小花费计算。
- 图解可以帮助理解问题的本质,明确每一步的状态转移。