问题:
难度: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 <= days.length <= 365
1 <= days[i] <= 365
days
is in strictly increasing order.costs.length == 3
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]];
// }
}