zl程序教程

您现在的位置是:首页 >  后端

当前栏目

198、【动态规划】leetcode ——983. 最低票价:记忆化搜索(C++版本)

C++LeetCode搜索规划 版本 动态 记忆 最低
2023-09-11 14:20:01 时间

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Problem: 983. 最低票价

思路

本题是根据days中的行程表,找到一个最小费用的购票方案。通常,当没有连续天数出行时,是购买一天的更便宜。但题中有可能会有多天连续出行的情况,此时如果一下子购买多天的行程票,可能会比只够买一张更便宜。因此,本题就是要找到当到达某一天时,是由一天前买的票到达当天更便宜,还是由七天前或三十天前到达当天更便宜。

解题方法

  • 动态规划五步曲:

(1)dp[i]含义: 第i天时,所需要的最低消费。

(2)递推公式: d p [ i ] = m i n ( d p [ i − 1 ] + c o s t [ 0 ] , d p [ i − 7 ] + c o s t [ 1 ] , d p [ i − 30 ] + c o s t [ 2 ] ) dp[i] = min(dp[i - 1] + cost[0], dp[i - 7] + cost[1], dp[i - 30] + cost[2]) dp[i]=min(dp[i1]+cost[0],dp[i7]+cost[1],dp[i30]+cost[2]),从上述三种情况中反推出来那种情况到达第i天时开销最小。

(3)dp数组初始化: dp[0] = 0,天数从1到n,0不合法为了便于计算dp[0]=0。而目标是求min,因此其余值设为INT_MAX。

(4)遍历顺序: 从左到右,按天数增长依次遍历。(这里注意,有可能会由7天或30天的票价,比1天的票价便宜的情况)

(5)举例:
image.png
image.png

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: O ( n ) O(n) O(n)

  • 空间复杂度:

添加空间复杂度, 示例: O ( n ) O(n) O(n)

Code


class Solution {
public:
    int mincostTickets(vector<int>& days, vector<int>& costs) {
        int n = days.back();
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        vector<int> has_trip(n + 1,false);
        for(int i = 0; i < days.size(); i++)        has_trip[days[i]] = true;

        for(int i = 1; i <= n; i++) {
            if(has_trip[i] == false) {
                dp[i] = dp[i - 1];
            } else {
                // 这里让b和c在小于0时,不变为0的原因是因为可能会有7天或30天的票,比1天的票更便宜的情况
                int a = dp[i - 1] + costs[0];
                int b = i - 7 >= 0 ? dp[i - 7] + costs[1] : costs[1];
                int c = i - 30 >= 0 ? dp[i - 30] + costs[2] : costs[2];
                dp[i] = min(a, min(b, c));
            }
        }

        return dp[n];
    }
};