983. 最低票价-M

2023-11-05 00:48
文章标签 最低 票价 983

本文主要是介绍983. 最低票价-M,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

983. 最低票价-M

label: dp不连续,滑动窗口

在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 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,并完成了你计划的每一天旅行。

提示:

  1. 1 <= days.length <= 365
  2. 1 <= days[i] <= 365
  3. days 按顺序严格递增
  4. costs.length == 3
  5. 1 <= costs[i] <= 1000

分析:这就找01背包问题类似,只不过这里days是断断续续,如果是连续的那直接dp就好办,断续就得用几个循环进行,不要以为这很烂,就是这种解法,重点在于处理“断“的地方。

  1. 滑动窗口,[i,j],想后看7和30天并更新票钱
  2. 使用连续的days方法,就和硬币一样,但是需要留意的是,断的地方要直接复制前边存在的那天,这样才能dp[i-7],dp[i-30]的方式进行
  3. 类似方法2,但是当时考虑不足,打了好几个补丁,比如没有处理好断的地方

需要注意的是,costs不是递增的,比如case: costs{7,2,15}

滑动窗口,并向后看:

package main
import "fmt"
/*
执行用时 :4 ms, 在所有 Go 提交中击败了66.67%的用户
内存消耗 :2.3 MB, 在所有 Go 提交中击败了100.00%的用户
*/
func mincostTickets(days []int, costs []int) int {dp:=make([]int,len(days)+1)for i:=0;i<len(days);i++{if dp[i+1]>dp[i]+costs[0]||dp[i+1]==0{dp[i+1]=dp[i]+costs[0]//后看1天}//滑动窗口,就是要在一个范围内进行来回比较for j:=i+1;j<=i+7&&j<=len(days)&&days[j-1]<days[i]+7;j++{if dp[j]>dp[i]+costs[1]||dp[j]==0{dp[j]=dp[i]+costs[1]}}for j:=i+1;j<=i+30&&j<=len(days)&&days[j-1]<days[i]+30;j++{if dp[j]>dp[i]+costs[2]||dp[j]==0{dp[j]=dp[i]+costs[2]}}}return dp[len(days)]
}
func main() {talbes:=[][]int{{1,4,6,7,8,20},{2,7,15},//11{1,2,3,4,5,6,7,8,9,10,30,31},{2,7,15},//17{1,4,6,7,8,20},{7,2,15},//6{1,2,3,4,6,8,9,10,13,14,16,17,19,21,24,26,27,28,29},{3,14,50},//50}for i:=0;i<len(talbes);i+=2{fmt.Println(mincostTickets(talbes[i],talbes[i+1]))}
}

使用连续的办法,向前看:

/*
执行用时 :4 ms, 在所有 Go 提交中击败了66.67%的用户
内存消耗 :2.8 MB, 在所有 Go 提交中击败了100.00%的用户
*/
func mincostTickets(days []int, costs []int) int {dp:=make([]int,days[len(days)-1]+1)mp:=make(map[int]int)for i:=0;i<len(days);i++{mp[days[i]]=1}for i:=1;i<=days[len(days)-1];i++{//不在则copyif _,ok:=mp[i];!ok{dp[i]=dp[i-1] //断的部分处理continue}//在则更新计算  dp[i]=dp[i-1]+costs[0]  //旅游日,分别向前看1,7,30天的价钱,pre:=0if i>=7{pre=i-7}//dp[i]表示0到i花费的最少价钱,都是前开后闭的区间形式if dp[pre]+costs[1]<dp[i]{dp[i]=dp[pre]+costs[1]}pre=0if i>=30{pre=i-30}if dp[pre]+costs[2]<dp[i]{dp[i]=dp[pre]+costs[2]}}return dp[days[len(days)-1]]
}

初次通过,打了几个补丁,就比较恶心了,记录这个丑陋的代码

/*
执行用时 :4 ms, 在所有 Go 提交中击败了66.67%的用户
内存消耗 :2.8 MB, 在所有 Go 提交中击败了100.00%的用户
*/
func mincostTickets2(days []int, costs []int) int {dp:=make([]int,days[len(days)-1]+1)dp[days[0]]=costs[0]for i:=1;i<len(days);i++{dp[days[i]]=dp[days[i-1]]+costs[0]}mp:=make(map[int]int)for i:=0;i<len(days);i++{mp[days[i]]=1}for i:=1;i<=days[len(days)-1];i++{if _,ok:=mp[i];!ok{dp[i]=dp[i-1]}else{if dp[i]==0{dp[i]=costs[0]}}if dp[i-1]+costs[0]<dp[i]{dp[i]=dp[i-1]+costs[0]}if i>=7 {if dp[i-7]+costs[1] < dp[i]{dp[i] = dp[i-7] + costs[1]}}else {if dp[0]+costs[1]<dp[i] {dp[i] = dp[0]+costs[1]}}if i>=30{if dp[i-30]+costs[2]<dp[i]{dp[i]=dp[i-30]+costs[2]}}else{//中间断的部分,也可以利用if dp[0]+costs[2]<dp[i]{dp[i]=dp[0]+costs[2]}}}return dp[days[len(days)-1]]
}

这篇关于983. 最低票价-M的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/346290

相关文章

App Store最低版本要求汇总

1,自此日期起: 2024 年 4 月 29 日 自 2024 年 4 月 29 日起,上传到 App Store Connect 的 App 必须是使用 Xcode 15 为 iOS 17、iPadOS 17、Apple tvOS 17 或 watchOS 10 构建的 App。将 iOS App 提交至 App Store - Apple Developer 2,最低XCode版本 Xcod

快递员送货最短路径和最低费用

一、问题定义 1、[快递公司送货策略](https://www.docin.com/p-700721704.html) 来自数学建模训练题目,解决办法“多目标动态规划” 二、相关论文 1.[A Model and Algorithm for the Courier Delivery Problem with Uncertainty(https://www.researchgate.net/

ESXi服务器无法安装Windows11:“不符合此版本的Windows所需最低系统要求“

目录 一、问题描述1.使用环境2.问题截图3.问题解析 二、解决方法Ⅰ1.按 Shift+F10 弹出命令提示符2.在弹出的Dos框中输入regedit,回车,进入注册表。3.打开HKEY_LOCAL_MACHINE\SYSTEM\Setup,并新建 LabConfig 的项,在 LabConfig 下创建两个 DWORD (32位)值4.关闭命令行重新点击安装,此时就会进入正常安装界面。

佰朔资本:股票最低多少股起买?各板块股票申购数量要求?

股票最低100股起购。在我国股票以手为生意单位,一手就等于100股。 1、主板:申报数量应当为100股或其整数倍,在卖出的时分,缺少100股时应该一次性卖出。 2、创业板:申报数量应当为100股或其整数倍,在卖出的时分,缺少100股时应该一次性卖出。 3、科创板:200股起购,以1股为单位递加,卖出股票时,余额缺少200股时应当一次性申报卖出。 4、北交所:100股起购,以1股为单位递加,

如果不得不喝酒,怎么样才能将酒精对身体的伤害降到最低?

不管处于什么目的,每个人都需要跟人打交道,需要社交,需要应酬,社交就避免不了在一起吃饭,按国人的习俗,吃饭自然离不开酒。说到喝酒,就绕不开一个话题——喝多少酒的问题。 不管什么酒,里面都含有酒精,只要含有酒精,那对人体就会有伤害。 如果必须喝酒,怎么样才能将酒精对身体的伤害降到最低?酱酒亮哥yutengtrade给大家准备了一些可以尽量减少酒精对身体伤害的方法: 餐前适量进食:在

1082:寻找最低数

题目描述 给你一个正整数A(1<=A<=100),输出A的最低数。 例如,给你A=26,我们可以将A化成二进制为11010,则A的最低数是10,输出10的十进制为2。 再例如,给你A=88,我们可以将A化成二进制为1011000,则A的最低数是1000,输出为8。 输入格式 输入包含多组测试样例。每行输入一个正整数A(1<=A<=100)。当输入0时,输入结束。 输出 对于每一个输入,

去掉一个最高分和最低分求平均值

青年歌手参加歌曲大奖赛,有10个评委打分(满分10分),试编程求选手的平均得分(去掉一个最高分和 一个最低分)。 解题分析: 水题,此题只需使用sort函数,并且去掉第一个和最后一个求平均值。 代码: #include <cstdio> #include <algorithm> #define MAXN 1000 using namespace std; int main() {

C语言编程:青年歌手参加歌曲大奖赛,有10个评委打分(满分10分),去掉最高最低分后,试编程求选手的平均得分

C语言编程:青年歌手参加歌曲大奖赛,有10个评委打分(满分10分),去掉最高最低分后,试编程求选手的平均得分: 代码如下: #include<stdio.h>void main(){int sum = 0,i;double avg,b;int a[10];int max,min;for(i=0;i<10;i++){scanf("%d",&a[i]);if(i==0)//只有第一次赋值m

案例二 树中两个结点的最低公共祖先

问题: 树中两个结点的最低公共祖先.     (1)是一颗二叉树,并且是二叉搜素树(根据二叉搜素树的性质求解)     (2)普通树中结点有指向父结点的指针(演变为两个链表求解第一个公共结点)     (3)一棵普通的树,树中的结点没有指向父结点的指针(最复杂的情况) 通用的解法如下: //记录结点的路径bool GetNodePath(TreeNode*

融资融券有哪些优势和风险,融资融券利息怎么算,利率最低是?4.0

融资融券的优势 1. 提高资金利用率:获得额外的资金或股票交易,提高资金利用率,扩大投资规模。 2. 降低投资风险:通过融资融券买入多只股票分散风险,降低单一股票持仓风险。 3. 增加投资收益:提供更多的交易机会和投资策略,如买入后加杠杆或卖空股票等。 4. 提高交易灵活性:融资融券可以在不同市场条件下交易,如在市场下跌时通过融券卖空获利。 融资融券的风险 1. 杠杆风险:融资融券是