每日算法:最小花费徒步

127 阅读2分钟

题目本体

题目名称:最小花费徒步

题目描述:

小明想从A徒步到B,总路程需要N天,每天需要消耗1份食物。从起点开始,小明每天都能遇到一个补给站,可以补充食物,不同补给站的食物价格可能不同。小明最多能同时携带K份食物,请问小明若要安全完成徒步,最少要花多少钱?

输入格式:

第一行为两个正整数N、K,代表总路程N天,最大负重K。 第二行为N个正整数,分别代表从第0天到N-1天,每一个补给站的食物价格。

输出格式:

输出一个正整数,代表最少花费金额。

示例:

plaintext
输入:
5 2
1 2 3 3 2

输出:
9

限制条件:

  • 30%的数据,N <= 100,K <= N,0 <= B <= 100
  • 80%的数据,N <= 10000,K <= 100,0 <= B <= 100
  • 100%的数据,N <= 1000000,K <= N,0 <= B <= 100

题目思路

初步理解:

这个问题是一个典型的动态规划问题,我们需要找到一种策略,使得小明在完成徒步的过程中花费最少的钱。

算法选择:

我们选择动态规划算法来解决这个问题,因为它可以有效地处理具有重叠子问题和最优子结构特性的问题。

关键点分析:

  • 贪心策略:在每一天,尽量购买最少的食物以满足需求,这样可以最小化花费。
  • 负重限制:在购买食物时,需要确保不超过最大负重K。

代码详解

java
public class Main {
    public static int solution(int n, int k, int[] prices) {
        // dp数组,dp[i]代表到达第i天时的最小花费
        int[] dp = new int[n];
        dp[0] = prices[0]; // 第一天至少要买一份食物

        // 动态规划填表
        for (int i = 1; i < n; i++) {
            // 如果当前天数减去负重范围内的花费大于前一天的花费,则更新dp[i]
            dp[i] = dp[i - 1] + prices[i];
            for (int j = 1; j <= k && i - j >= 0; j++) {
                dp[i] = Math.min(dp[i], dp[i - j] + prices[i]);
            }
        }
        return dp[n - 1]; // 返回最后一天的花费,即最小花费
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution(5, 2, new int[]{1, 2, 3, 3, 2}) == 9);
        System.out.println(solution(6, 3, new int[]{4, 1, 5, 2, 1, 3}) == 9);
        System.out.println(solution(4, 1, new int[]{3, 2, 4, 1}) == 10);
    }
}

总结分析

算法复杂度:

  • 时间复杂度:O(N * K),其中N是天数,K是最大负重。
  • 空间复杂度:O(N),需要一个大小为N的数组来存储动态规划的状态。

算法优缺点:

  • 优点:能够找到最优解,适用于这个问题。
  • 缺点:对于大数据量,时间复杂度较高,可能需要优化。

特殊情况处理:

  • 如果K大于N,即最大负重大于总天数,那么不需要考虑负重限制。