火車票有三種不一樣的銷售方式:
一張爲期一天的通行證售價爲 costs[0] 美圓;
一張爲期七天的通行證售價爲 costs[1] 美圓;
一張爲期三十天的通行證售價爲 costs[2] 美圓。
通行證容許數天無限制的旅行。 例如,若是咱們在第 2 天得到一張爲期 7 天的通行證,那麼咱們能夠連着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。
返回你想要完成在給定的列表 days 中列出的每一天的旅行所須要的最低消費。
示例 1:
輸入:days = [1,4,6,7,8,20], costs = [2,7,15]
輸出:11
解釋:
例如,這裏有一種購買通行證的方法,可讓你完成你的旅行計劃:
在第 1 天,你花了 costs[0] = $2 買了一張爲期 1 天的通行證,它將在第 1 天生效。
在第 3 天,你花了 costs[1] = $7 買了一張爲期 7 天的通行證,它將在第 3, 4, ..., 9 天生效。
在第 20 天,你花了 costs[0] = $2 買了一張爲期 1 天的通行證,它將在第 20 天生效。
你總共花了 $11,並完成了你計劃的每一天旅行。
示例 2:
輸入:days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15]
輸出:17
解釋:
例如,這裏有一種購買通行證的方法,可讓你完成你的旅行計劃:
在第 1 天,你花了 costs[2] = $15 買了一張爲期 30 天的通行證,它將在第 1, 2, ..., 30 天生效。
在第 31 天,你花了 costs[0] = $2 買了一張爲期 1 天的通行證,它將在第 31 天生效。
你總共花了 $17,並完成了你計劃的每一天旅行。
提示:
1 <= days.length <= 365
1 <= days[i] <= 365
days 按順序嚴格遞增
costs.length == 3
1 <= costs[i] <= 1000
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/minimum-cost-for-tickets
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。
複製代碼
我這裏的思路是用動態劃分,把1,到365天的每一天的最小票價計算出來,分爲3種狀況買日票,買月票,買周票,3種狀況,數組
public static void main(String[] args) {
int days []={1,4,6,7,8,20};
int costs[] ={2,7,15};
int tsts = new Solution().mincostTickets(days,costs);
System.out.println(tsts);
}
static class Solution {
public int mincostTickets(int[] days, int[] costs) {
// 將重新年到某一天的花過的全部錢數所有記錄起來。
int[] lastAllDaysCost = new int[366];
// days的下標,確保遍歷365天時,以便於知道下次旅遊的日期。
int dayIdx = 0;
// 日,月,年的花費。
int ticketDay = costs[0];
int ticketWeek = costs[1];
int ticketMonth = costs[2];
// 由於是第一天,因此過去的總花費爲0
lastAllDaysCost[0] = 0;
// lastAllCost[i] 是截至到今年的第 i 天的總花費.
// 模擬新年的第一天跑到旅行的最後一天。
for (int today = 1; today <= 365; today++) {
if(dayIdx >= days.length){
//執行玩days數組的裏面的數據了
break;
}
// 判斷今天是否屬於旅行日。
if (days[dayIdx] != today) {
// 若是這一天不旅行那麼直接把上一天的過去總花費拿過來直接使用。
lastAllDaysCost[today] = lastAllDaysCost[today - 1];
continue;
}
// 開始等待下一個待旅行的日子到來。
dayIdx++;
// 若是一月前,買了月票,會不會更便宜?
// 若是一週前,買了周票,會不會更便宜?
// 若是都不會的話,那我暫時先買日票試試唄。
lastAllDaysCost[today] = Math.min(
Math.min(
lastAllDaysCost[Math.max(0, today - 1)] + ticketDay
, lastAllDaysCost[Math.max(0, today - 7)] + ticketWeek)
, lastAllDaysCost[Math.max(0, today - 30)] + ticketMonth);
}
return lastAllDaysCost[days[days.length - 1]];//最後一天後之後就沒有花費
}
}
}
複製代碼