最低票价

博客围绕火车旅行最低消费问题展开,已知旅行日期数组和三种火车票销售方式,要完成给定日期旅行。解题采用动态规划,通过比较昨天费用加一天费用、7天前费用加7天费用、30天前费用加30天费用,取最小值作为当天最低费用。

题目:
在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。
火车票有三种不同的销售方式:
一张为期一天的通行证售价为 costs[0] 美元;
一张为期七天的通行证售价为 costs[1] 美元;
一张为期三十天的通行证售价为 costs[2] 美元。
通行证允许数天无限制的旅行。 例如,如果我们在第 2 天获得一张为期 7 天的通行证,那么我们可以连着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。

返回你想要完成在给定的列表 days 中列出的每一天的旅行所需要的最低消费。
题目解析:
这道题用动态规划是最合适的,解题思路是昨天的费用加上只旅游一天的费用的和 与 7天前的费用加上旅行7天的费用的和 与 30天前的加上旅行30天所需费用的和三者最小的就是今天的最低费用,如果旅行天数不满足7天或者是30天,也应该进行比较计算,因为题目并没有说7这两个套餐不一定比天数不满这些天所计算的费用高。

int mincostTickets(vector<int>& days, vector<int>& costs) {
	int end_day = days[days.size() - 1];
	vector<vector<int>> buff(2, vector<int>(end_day + 1));
	for (int i = 0; i < days.size(); i++)
		buff[0][days[i]] = 1;
	for (int i = 1; i <= end_day; i++){
		if (!buff[0][i]){
			buff[1][i] = buff[1][i - 1];
			continue;
		}
		if (i < 7)
			buff[1][i] = min(buff[1][i - 1] + costs[0], min(costs[1], costs[2]));
		else if (i < 30)
			buff[1][i] = min(buff[1][i - 1] + costs[0], min(buff[1][i - 7] + costs[1], costs[2]));
		else
			buff[1][i] = min(min(buff[1][i - 1] + costs[0], buff[1][i - 7] + costs[1]), buff[1][i - 30] + costs[2]);
	}
	return buff[1][end_day];
}
在C++中解决最低票价问题,可以采用动态规划的方法。以下是一个具体的C++代码实现及解释: ```cpp #include <vector> #include <algorithm> class Solution { public: int mincostTickets(vector<int>& days, vector<int>& costs) { // 状态定义: f[i] 表示 i 天及之后旅行所需的最小花费 int f[366]{}; // 标注哪些天出门 for (int v: days) f[v] = 1; // 由于状态转移是逆向的,所以倒序。初始状态为第365天,如果出门了,因为是最后一天所以买一张最便宜的通行证就行了,否则f[365]就是0 f[365] = f[365] == 1 ? min(costs[0], min(costs[1], costs[2])) : 0; for (int i = 364; i > -1; --i) { if (f[i] > 0) { int d1 = i+1 < 366 ? costs[0] + f[i+1] : costs[0]; int d7 = i+7 < 366 ? costs[1] + f[i+7] : costs[1]; int d30 = i+30 < 366 ? costs[2] + f[i+30] : costs[2]; // 如果在第i天出门,那么f[i]要更新,买一天的票的成本加上下一天的最少费用,买七天的票的成本加上之后第8天的最少费用,买30天的票的成本加上第30天之后的最少费用,他们三者取最小值 f[i] = min(d1, min(d7,d30)); } else { // 如果不出门就是下一天的最小费用 f[i] = f[i+1]; } } return f[0]; } }; ``` ### 代码解释 1. **状态定义**:`f[i]` 表示 `i` 天及之后旅行所需的最小花费。 2. **标注出行日期**:通过遍历 `days` 数组,将出行的日期在 `f` 数组中标记为 `1`。 3. **初始化**:对于第 `365` 天,如果当天出行,则购买三种票中最便宜的一张;如果不出行,则花费为 `0`。 4. **状态转移**: - 当第 `i` 天出行时,分别计算购买一天、七天和三十天票的花费,并取最小值更新 `f[i]`。 - 当第 `i` 天不出行时,`f[i]` 等于 `f[i + 1]`。 5. **返回结果**:最终返回 `f[0]`,即整个旅行计划所需的最小花费。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值