题目链接: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]; }};