最低票价(记忆化搜索/动态规划)
题目链接:https://leetcode.cn/problems/minimum-cost-for-tickets/
题意:
给你一个数组days[]代表旅行的日期,一个数组costs[],可以分别选择1天或7天或30天的票,问你使旅行结束所需要的最低票价是多少
示例 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,并完成了你计划的每一天旅行。
思路:
暴力尝试->记忆化搜索(挂缓存表)->严格位置依赖的动态规划
记忆化搜索solution
递归搜索第days[i]天的最低(min)票价,通过dp数组来进行剪枝;
class Solution {
public:
int duration[3]={1,7,30};
int mincostTickets(vector<int>& days, vector<int>& costs) {
int dp[365];
memset(dp,0x3f3f3f3f,sizeof(dp));
return f(dp,0,days,costs);
}
int f(int dp[],int i,vector<int>days,vector<int>costs)
{
if(i==days.size())return 0;
if(dp[i]!=0x3f3f3f3f)return dp[i];
int ans=INT_MAX;
for(int k=0,j=i;k<3;k++)
{
while(j<days.size()&&days[i]+duration[k]>days[j])
{
j++;
}
ans=min(ans,costs[k]+f(dp,j,days,costs));
}
dp[i]=ans;
return ans;
}
};
DP
class Solution {
public:
int duration[3]={1,7,30};
int mincostTickets(vector<int>& days, vector<int>& costs) {
int dp[365];
int n=days.size();
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[n]=0;
for(int i=n-1;i>=0;i--)
{
for(int k=0,j=i;k<3;k++)
{
while(j<n&&days[i]+duration[k]>days[j])
{
j++;
}
dp[i]=min(dp[i],costs[k]+dp[j]);
}
}
return dp[0];
}
};

浙公网安备 33010602011771号