LeetCode 983. 最低票价 (中规中矩的DP)

最低票价
明显DP的阶段就以每一个出现的日期。
d p [ i ] dp[i] 表示完成 d a y s [ 0 ] days[0] ~ d a y s [ i ] days[i] 所需要的最小花费,然后考虑 d p [ i + 1 ] dp[i+1] ,它这一天既可以直接购买一张 c o s t [ 0 ] cost[0] ,也许和前面的某一天或某几天共同买一张7天或30天的票。
初始化, d p [ ] dp[] 数组为无穷大,在完成 d p [ i ] dp[i] 后,考虑接下来的安排时,在 i + 1 i+1 天可能的情况是买1天、7天、30天。
举个例子,

days: 1 2 3 4 5 6 7
costs 3 7 15
第一阶段 1         3
第二阶段 1 2       6
第三阶段 1 2 3     7
第四阶段 1 2 3 4   7

之所以第三阶段的最小花费为 7 而不是6+3=9。
实际上是因为, d p [ 0 ] + 7 < d p [ 2 ] + 3 dp[0]+7<dp[2]+3 (dp[0]是我设定的旅行0天的最小花费,当然也就是0了)

class Solution {
public:
    int mincostTickets(vector<int>& days, vector<int>& costs) {
        int n = days.size();
        vector<int> dp(n+1,(int)1e9);
        dp[0] = 0;
        days.insert(days.begin(),0); //下标从1开始
        for(int i=0;i<n;i++){
            for(int j=i+1;j<=n;j++){
                if(days[j]-days[i+1]>=30) break;
                if(days[j]-days[i+1]<1){
                    dp[j] = min(dp[j],dp[i]+costs[0]);
                }
                if(days[j]-days[i+1]<7){
                    dp[j] = min(dp[j],dp[i]+costs[1]);
                }
                if(days[j]-days[i+1]<30){
                    dp[j] = min(dp[j],dp[i]+costs[2]);
                }
            }
        }
        return dp[n];
    }
};

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/107552562