983. 最低票价

Problem: 983. 最低票价

文章目录

  • 思路
  • 解题方法
  • 复杂度
  • Code

思路

在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。
火车票有 三种不同的销售方式 :
一张 为期一天 的通行证售价为 costs[0] 美元;
一张 为期七天 的通行证售价为 costs[1] 美元;
一张 为期三十天 的通行证售价为 costs[2] 美元。
通行证允许数天无限制的旅行。 例如,如果我们在第 2 天获得一张 为期 7 天 的通行证,那么我们可以连着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。
返回 你想要完成在给定的列表 days 中列出的每一天的旅行所需要的最低消费。

对于这个问题,我们使用动态规划的方法来解决。我们定义dp[i]为从第i天到最后一天的最小花费。对于每一天,我们都有三种选择:购买一天的通行证,购买七天的通行证,或者购买三十天的通行证。我们选择花费最小的那一种

解题方法

状态转移方程为:dp[i] = min(costs[k] + dp[j]),其中k在{0, 1, 2}中选择,j是第一个不被第i天购买的通行证覆盖的天。 这个方程在给出的代码中被使用来迭代更新dp数组,从旅行计划的最后一天开始,到第一天结束。最后,dp[0]就是整个旅行计划的最小花费。

复杂度

时间复杂度:

时间复杂度 O ( n ) O(n) O(n)

空间复杂度:

空间复杂度 O ( n ) O(n) O(n)

Code

class Solution {
    public int[] addDay = new int[] { 1, 7, 30 };
    public int MAXN = 366;
    public int[] dp = new int[MAXN];

    public int mincostTickets(int[] days, int[] costs) {
        int n = days.length;
        Arrays.fill(dp, 0, n + 1, Integer.MAX_VALUE);
        dp[n] = 0;
        for (int i = n - 1; i >= 0; i--) {
            for (int k = 0, j = i; k < 3; k++) {
                while (j < days.length && days[i] + addDay[k] > days[j]) {
                    j++;
                }
                dp[i] = Math.min(dp[i], costs[k] + dp[j]);
            }
        }
        return dp[0];
    }

}

你可能感兴趣的:(算法,刷题,动态规划,java,算法)