力扣题解 983

大家好,欢迎来到无限大的判断,祝大家国庆假期愉快

题目描述(中等)

最低票价
在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。

火车票有 三种不同的销售方式 :

  • 一张 为期一天 的通行证售价为 costs[0] 美元;
  • 一张 为期七天 的通行证售价为 costs[1] 美元;
  • 一张 为期三十天 的通行证售价为 costs[2] 美元。

通行证允许数天无限制的旅行。 例如,如果我们在第 2 天获得一张 为期 7 天 的通行证,那么我们可以连着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。

返回 你想要完成在给定的列表 days 中列出的每一天的旅行所需要的最低消费 。

这道题是一个典型的动态规划问题,我们需要通过购买合理的火车票来最小化旅行的费用。对于给定的一组旅行天数 days 和各种票价 costs,我们要找到最低的总费用策略。
在这里插入图片描述


题目解析

输入/输出描述
  • 输入

    • 一个整数数组 days 表示你需要旅行的天数。
    • 一个整数数组 costs,其中 costs[0] 是为期一天的票价,costs[1] 是为期七天的票价,costs[2] 是为期三十天的票价。
  • 输出

    • 一个整数,即完成所有给定旅行天数所需的最低费用。
问题要求

对于需要旅行的每一天,我们有三种购买票的选择:一天,七天,或者三十天。我们要通过合理选择票种,在满足旅行需要的同时,使总花费最小。

解题思路

  1. 动态规划定义

    • dp[i] 表示从第 1 天到第 i 天的旅行最低费用。
  2. 转移方程

    • 如果第 i 天没有安排旅行,那么 dp[i] = dp[i-1]
    • 如果有旅行安排,dp[i] 可以从以下三种情况中得来:
      • 使用 1 天票:dp[i] = dp[i-1] + costs[0]
      • 使用 7 天票:dp[i] = dp[i-7] + costs[1](这里注意如果 i < 7,则 dp[i-7] 可以看作 0
      • 使用 30 天票:dp[i] = dp[i-30] + costs[2](这里注意如果 i < 30,则 dp[i-30] 可以看作 0
    • 我们选择三种情况中费用最低的方案:dp[i] = min(dp[i-1] + costs[0], dp[i-7] + costs[1], dp[i-30] + costs[2])
  3. 初始条件

    • dp[0] = 0(第 0 天不需花费)
  4. 最终目标

    • dp[days[i]],其中 i 是最大旅行日数,考虑只需处理在 days 中的天数。

C语言代码实现

#include <stdio.h>
#include <limits.h>

int mincostTickets(int* days, int daysSize, int* costs, int costsSize) {
    int dp[366] = {0};  // Using 366 because days range from 1 to 365
    
    int dayIndex = 0;
    
    for (int i = 1; i <= 365; i++) {
        if (dayIndex >= daysSize || i != days[dayIndex]) {
            dp[i] = dp[i - 1];
        } else {
            int oneDayPass = dp[i - 1] + costs[0];
            int sevenDayPass = dp[i - 7 > 0 ? i - 7 : 0] + costs[1];
            int thirtyDayPass = dp[i - 30 > 0 ? i - 30 : 0] + costs[2];
            
            dp[i] = fmin(oneDayPass, fmin(sevenDayPass, thirtyDayPass));
            dayIndex++;
        }
    }
    
    return dp[days[daysSize - 1]];
}

int main() {
    int days[] = {1, 4, 6, 7, 8, 20};
    int costs[] = {2, 7, 15};
    int result = mincostTickets(days, 6, costs, 3);
    printf("Minimum cost: %d\n", result);
    return 0;
}

C++代码实现

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int mincostTickets(vector<int>& days, vector<int>& costs) {
    vector<int> dp(366, 0);
    
    int n = days.size();
    int dayIndex = 0;
    
    for (int i = 1; i <= 365; i++) {
        if (dayIndex >= n || i != days[dayIndex]) {
            dp[i] = dp[i - 1];
        } else {
            int oneDayPass = dp[i - 1] + costs[0];
            int sevenDayPass = dp[max(0, i - 7)] + costs[1];
            int thirtyDayPass = dp[max(0, i - 30)] + costs[2];
    
            dp[i] = min({oneDayPass, sevenDayPass, thirtyDayPass});
            dayIndex++;
        }
    }
    
    return dp[days[n - 1]];
}

int main() {
    vector<int> days = {1, 4, 6, 7, 8, 20};
    vector<int> costs = {2, 7, 15};
    int result = mincostTickets(days, costs);
    cout << "Minimum cost: " << result << endl;
    return 0;
}

算法分析

  • 时间复杂度:O(n),其中 ndays 的大小,因为我们只遍历每一个旅行天数,并对其更新一次。
  • 空间复杂度:O(365),主要用于 dp 数组的存储。
  • 该方案特别高效,因为对于每一个天数,我们只需决定三种选择中哪种最优,并且通过比较每次操作来更新 dp 的值。

结论

动态规划的关键在于将较大的问题划分为多个子问题,并从小到大不断求解。因此,通过合理地定义状态和状态转移方程,这个问题可以被有效解决。上述方案巧妙地利用了 dp 技巧,使得问题分析更为简洁,并能保证所需的最小费用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/886171.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Charles(青花瓷)抓取https请求

文章目录 前言Charles&#xff08;青花瓷&#xff09;抓取https请求 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&…

kafka下载配置

下载安装 参开kafka社区 zookeeperkafka消息队列群集部署https://apache.csdn.net/66c958fb10164416336632c3.html 下载 kafka_2.12-3.2.0安装包快速下载地址分享 官网下载链接地址&#xff1a; 官网下载地址&#xff1a;https://kafka.apache.org/downloads 官网呢下载慢…

2024/10/2 408 20题

c d d b b a b c b b a d c d a c

java基础 day1

学习视频链接 人机交互的小故事 微软和乔布斯借鉴了施乐实现了如今的图形化界面 图形化界面对于用户来说&#xff0c;操作更加容易上手&#xff0c;但是也存在一些问题。使用图形化界面需要加载许多图片&#xff0c;所以消耗内存&#xff1b;此外运行的速度没有命令行快 Wi…

【华为HCIP实战课程一】OSPF相关基础介绍及基础配置,网络工程师必修

一、OSPF介绍 开放式最短路径优先协议OSPF(Open Shortest Path First),IPv4使用的OSPFv2,针对IPv6使用OSPFv3协议。 二、为什么需要OSPF OSPF出现之前,网络广泛使用RIP路由协议,RIP由于最大16跳数限制无法适应大型网络,RIP是基于距离矢量算法的路由协议,应用在大型网…

过去8年,编程语言的流行度发生了哪些变化?PHP下降,Objective-C已过时

前天有一个汇总9个不同排名数据的“地表最强”编程语言排行榜&#xff0c;为了更好地理解语言流行度的变化&#xff0c;作者将2016年的类似调查结果与2024年的数据进行了比较。 虽然2016年的调查只包含6个排名&#xff0c;但它仍然提供了宝贵的参考数据。 我们来看看详细的情…

JSON的C实现(上)

JSON的C实现&#xff08;上&#xff09; JSON的C实现&#xff08;上&#xff09;前言JSON简介JSON的C实现思路小结 JSON的C实现&#xff08;上&#xff09; 前言 JSON是众多项目中较为常见的数据交换格式&#xff0c;为不同项目、系统间的信息交换提供了一个规范化标准。JSON…

Unity八股总结

这里写目录标题 OnEnable、Awake、Start运行时的发生顺序&#xff1f;哪些可能在同一个对象周期中反复的发生&#xff1f;动态加载资源的方式?Unity3d脚本从唤醒到销毁有着一套比较完整的生命周期&#xff0c;请列出系统自带的几个重要的方法。物理更新一般放在哪个系统函数里…

查找与排序-插入排序

排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要访问外存。常见的内部排序算法有&#xff1a;插入排序、希尔排序、选择排序…

Arduino UNO R3自学笔记15 之 Arduino如何驱动数码管?

注意&#xff1a;学习和写作过程中&#xff0c;部分资料搜集于互联网&#xff0c;如有侵权请联系删除。 前言&#xff1a;学习使用数码管。 1.数码管介绍 数码管的一种是半导体发光器件&#xff0c;数码管可分为七段数码管和八段数码管&#xff0c;区别在于八段数码管比七段数…

L0-Linux-关卡材料提交

SSH全称Secure Shell&#xff0c;中文翻译为安全外壳&#xff0c;它是一种网络安全协议&#xff0c;通过加密和认证机制实现安全的访问和文件传输等业务。SSH 协议通过对网络数据进行加密和验证&#xff0c;在不安全的网络环境中提供了安全的网络服务。 SSH 是&#xff08;C/S…

QSqlDatabase在多线程中的使用

Qt中多线程使用数据库_qt数据库管理类支持多数据库,多线程-CSDN博客 1. 代码&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError>…

【深度学习】05-Rnn循环神经网络-01- 自然语言处理概述/词嵌入层/循环网络/文本生成案例精讲

循环神经网络&#xff08;RNN&#xff09;主要用于自然语言处理的。 循环神经网络&#xff08;RNN&#xff09;、卷积神经网络&#xff08;CNN&#xff09;和全连接神经网络&#xff08;FCN&#xff09;是三种常见的神经网络类型&#xff0c;各自擅长处理不同类型的数据。下面…

RabbitMQ应用

RabbitMQ 共提供了7种⼯作模式, 进⾏消息传递 一、七种模式的概述 1、Simple(简单模式) P:生产者,就是发送消息的程序 C:消费者,就是接收消息的程序 Queue:消息队列,类似⼀个邮箱, 可以缓存消息; ⽣产者向其中投递消息, 消费者从其中取出消息 特点: ⼀个⽣产者P,⼀…

负载均衡--相关面试题(六)

在负载均衡的面试中&#xff0c;可能会遇到一系列涉及概念、原理、实践应用以及技术细节的问题。以下是一些常见的负载均衡面试题及其详细解答&#xff1a; 一、什么是负载均衡&#xff1f; 回答&#xff1a;负载均衡是一种将网络请求或数据传输工作分配给多个服务器或网络资源…

SpringSession微服务

一.在linux中确保启动起来redis和nacos 依赖记得别放<dependencyManagement></dependencyManagement>这个标签去了 1.首先查看已经启动的服务 docker ps 查看有没有安装redis和nacos 2.启动redis和nacos 发现没有启动redis和nacos,我们先来启动它。&#xff0c;…

计算机视觉学习路线:从基础到进阶

计算机视觉学习路线&#xff1a;从基础到进阶 计算机视觉&#xff08;Computer Vision&#xff09;是人工智能和机器学习领域中重要的分支&#xff0c;致力于让计算机能够理解和分析图像、视频等视觉信息。随着深度学习的发展&#xff0c;计算机视觉的应用变得越来越广泛&…

音视频入门基础:FLV专题(7)——Tag header简介

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;3&#xff09;——FLV header简介》中可以知道&#xff0c; 在FLV header之后&#xff0c;FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…

【C++】“list”的介绍和常用接口的模拟实现

【C】“list”的介绍和常用接口的模拟实现 一. list的介绍1. list常见的重要接口2. list的迭代器失效 二. list常用接口的模拟实现&#xff08;含注释&#xff09;三. list与vector的对比 一. list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xf…

2025 年 IT 前景:机遇与挑战并存,人工智能和云计算成重点

云计算de小白 投资人工智能&#xff1a;平衡潜力与实用性 到 2025 年&#xff0c;人工智能将成为 IT 支出的重要驱动力&#xff0c;尤其是在生成式人工智能领域。人工智能的前景在于它有可能彻底改变业务流程、增强决策能力并开辟新的收入来源。然而&#xff0c;现实情况更加微…