Minimum Cost For Tickets
题目描述
leetcode.983
In a country popular for train travel, you have planned some train travelling one year in advance. The days of the year that you will travel is given as an array days. Each day is an integer from 1 to 365.
Train tickets are sold in 3 different ways:
a 1-day pass is sold for costs[0] dollars;
a 7-day pass is sold for costs[1] dollars;
a 30-day pass is sold for costs[2] dollars.
The passes allow that many days of consecutive travel. For example, if we get a 7-day pass on day 2, then we can travel for 7 days: day 2, 3, 4, 5, 6, 7, and 8.
Return the minimum number of dollars you need to travel every day in the given list of days.
在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。
火车票有三种不同的销售方式:
一张为期一天的通行证售价为 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,并完成了你计划的每一天旅行。
解题
就是说一共有365天,days数组中告诉哪几天要出去旅游,costs为对应1、7、30天的通行证,通行证可以旅游对应天数,要求算出最低消费。
可以分为两种情况:
1.如果当天不需要出去旅游,则当前花费和上一天相等。
2.如果当天需要出去旅游,有三种情况会到达当天,i-1天买1天的通行证,i-7天买7天的通行证,i-30天买30天的通行证,和爬台阶类似。
因此状态转移方程为
1.当天不要出去旅游:
d
p
[
i
]
=
d
p
[
i
−
1
]
dp[i] = dp[i-1]
dp[i]=dp[i−1]
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[i−1]+cost[0],dp[i−7]+cost[1],dp[i−30]+cost[2])
class Solution {
public:
int mincostTickets(vector<int>& days, vector<int>& costs) {
int n = days.size();
vector<int> vec(366,0);
for(int i=0;i<n;i++)
{
vec[days[i]] = 1;//记录365天,哪几天要出去旅游
}
for(int i=1;i<vec.size();i++)
{
if(vec[i] == 0)//不出去旅游
{
vec[i] = vec[i-1];
}
else//出去旅游
{
vec[i] = min(vec[i-1]+costs[0],min(vec[max(0,i-7)]+costs[1],vec[max(0,i-30)]+costs[2]));
//注意vec的索引要大于等于0
}
}
return vec[days[n-1]];
}
};