[Leetcode学习-java]Minimum Cost For Tickets(票据最小花费)

问题:

难度:medium

说明:

阅读理解题

有 1 天 7 天 30 天的票据,每个票据有不同价格,输入一个 costs[] 3 种票据的花费,还有一个 days[] 行程表,你会在 365 天某天内进行旅游,那么你最小花费应该是多少。

问题链接:https://leetcode.com/problems/minimum-cost-for-tickets/

相关问题:

Word Search II(二维数组找相同字符串):https://blog.csdn.net/qq_28033719/article/details/107055702

输入范围:

  1. 1 <= days.length <= 365
  2. 1 <= days[i] <= 365
  3. days is in strictly increasing order.
  4. costs.length == 3
  5. 1 <= costs[i] <= 1000

输入案例:

Example 1:
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.

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

我的代码:

这就跟阅读理解一样,理解了之后就知道,其实就背包问题,不过票据重量为 days 三种,这样就可以不用循环三次了,直接写死。可以用 366 长度数组直接处理,也可以用 30 天做周期进行处理,不过因为 a % 30 的时钟周期有可能长点,只有机器可以就能够忽略

class Solution {
    public int mincostTickets(int[] days, int[] costs) {
        int[] dp = new int[30];
        int dL = days.length, last = days[dL - 1], dIndex = 0; // 多了个 index 标记 days
        for(int i = days[0];i <= last;i ++) {
            if(i != days[dIndex]) dp[i % 30] = dp[(i - 1) % 30];
            else {
                dp[i % 30] = Math.min(Math.min(costs[0] + dp[(i - 1) % 30], 
                                  costs[1] + dp[Math.max(0, i - 7) % 30]), 
                                  costs[2] + dp[Math.max(0, i - 30) % 30]);
                dIndex ++;
            }
        }
        return dp[days[dL - 1] % 30];
    }

    // 使用 366 容量的数组,把每一天都存放起来
    // public int mincostTickets(int[] days, int[] costs) {
    //     int dL = days.length; int[] dp = new int[366];
    //     for(int i = 0;i < dL;i ++) dp[days[i]] = 1;
    //     for(int i = 1;i < 366;i ++) {
    //         if(dp[i] == 0) dp[i] = dp[i - 1];
    //         else dp[i] = Math.min(Math.min(costs[0] + dp[i - 1], 
    //                               costs[1] + dp[Math.max(0, i - 7)]), 
    //                               costs[2] + dp[Math.max(0, i - 30)]);
    //     }
    //     return dp[days[dL - 1]];
    // }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值