leetcode | 983. Minimum Cost For Tickets (动态规划)

  • 最近做的leetcode有点多,没时间更新博客,后面多做一些基础算法题;
  • 今天上午周赛做了一道DP题目,不过当时没有想到使用DP,囧

题目

给定一个数组days,表示今年的旅行计划,你可以买单日票,周票和月票

  • 求:旅行的最低花费
  • 如下特点:1 <= days.length <= 365;1 <= days[i] <= 365,元素特点是单调递增的。

Input: days = [1,4,6,7,8,20], costs = [2,7,15]
Output: 11
Explanation:
For example, here is one way to buy passes that lets you travel your travel plan:
On day 1, you bought a 1-day pass for costs[0] = $2, which covered day 1.
On day 3, you bought a 7-day pass for costs[1] = $7, which covered days 3, 4, …, 9.
On day 20, you bought a 1-day pass for costs[0] = $2, which covered day 20.
In total you spent $11 and covered all the days of your travel.

分析

  • 这题不用DP,也暂时没想到其他时间复杂度较低的解法;
  • DP思路比较简单,但是根据题目特点有O(n)和O(365)两种解法

解法1:

    public int mincostTickets(int[] days, int[] costs) {
        // dp[i + 1] .. days[0, .., i]的最优解
        // dp[i] = min(dp[week] + costs[1], dp[month] + costs[2], dp[i - 1] + costs[0]);
        int week = 0;
        int month = 0;
        int[] dp = new int[days.length + 1];
        dp[0] = 0;
        for (int i = 0; i < days.length; i++) {
            while(days[week] < days[i] - 6) {
                week++;
            }
            while(days[month] < days[i] - 29) {
                month++;
            }
            int tmp = Math.min(dp[i] + costs[0], dp[week] + costs[1]);
            dp[i + 1] = Math.min(tmp, dp[month] + costs[2]);
        }
        return dp[days.length];
    }

解法2:

public int mincostTickets(int[] days, int[] costs) {
        boolean[] dayIncluded = new boolean[366];
        for (int day : days) {
            dayIncluded[day] = true;
        }
        int[] minCost = new int[366];
        minCost[0] = 0;
        for (int day = 1; day <= 365; ++day) {
            if (!dayIncluded[day]) {
                minCost[day] = minCost[day-1];
                continue;
            }
            int min;
            min = minCost[day-1] + costs[0];
            min =Math.min(min, minCost[Math.max(0, day-7)] + costs[1]);
            min = Math.min(min, minCost[Math.max(0, day-30)] + costs[2]);
            minCost[day] = min;
        }

        return minCost[365];

    }

你可能感兴趣的:(leetcode)