当前位置: 首页 > news >正文

动态规划 dp 题目与讲解

本文为在学动规的朋友们列一个题目。大家可以自己写一写,本人自己写起来觉得挺有帮助的。



[信息与未来 2026] 旅行计划

题目描述

Dr. X 想从城市000出发前往城市nnn。对于所有满足0≤i≤n−10 \le i \le n - 10in1的整数iii,城市iii与城市i+1i + 1i+1之间都有高铁和飞机两种出行方式:

  • 坐高铁从城市iii到城市i+1i + 1i+1花费的时间为gig_igi
  • 坐飞机从城市iii到城市i+1i + 1i+1花费的时间为fif_ifi

然而,Dr. X 很害怕坐飞机,因此他希望整个行程中乘坐飞机的次数不得超过kkk次。

为了减少坐飞机的次数,Dr. X 可以选择从城市iii直接飞到城市i+ji + ji+j(j≥1j \ge 1j1),总飞行时间等于途经各段航线的飞行时间之和fi+fi+1+⋯+fi+j−1,\begin{aligned} f_i + f_{i+1} + \cdots + f_{i+j-1}, \end{aligned}fi+fi+1++fi+j1,但这样一次连续飞行只算乘坐一次飞机。请计算 Dr. X 从城市000出发到达城市nnn所需的最少时间。

输入格式

输入第一行包含两个整数nnnkkk,分别表示路线的数量和最多允许的坐飞机次数。

第二行包含nnn个空格分隔的整数g0,g1,…,gn−1g_0, g_1, \ldots, g_{n-1}g0,g1,,gn1,其中gig_igi表示从城市iii坐高铁到城市i+1i + 1i+1所花费的时间。

第三行包含nnn个空格分隔的整数f0,f1,…,fn−1f_0, f_1, \ldots, f_{n-1}f0,f1,,fn1,其中fif_ifi表示从城市iii坐飞机到城市i+1i + 1i+1所花费的时间。

输出格式

输出一个整数,表示 Dr. X 从城市000到达城市nnn所需的最少时间。

输入输出样例 #1

输入 #1

3 1 4 6 8 1 11 4

输出 #1

14

输入输出样例 #2

输入 #2

3 2 4 6 8 1 11 4

输出 #2

11

输入输出样例 #3

输入 #3

3 1 4 6 8 1 7 4

输出 #3

12

说明/提示

样例 1 解释

  • 最快的方式是从城市000坐高铁到城市111,再从城市111坐高铁到城市222,最后从城市222坐飞机到城市333,总耗时为4+6+4=144 + 6 + 4 = 144+6+4=14。总共坐飞机111次,满足限制。

样例 2 解释

  • 最快的方式是从城市000坐飞机到城市111,从城市111坐高铁到城市222,从城市222坐飞机到城市333,总耗时为1+6+4=111 + 6 + 4 = 111+6+4=11。总共坐飞机222次。

样例 3 解释

  • 尽管g1<f1g_1 < f_1g1<f1,但在只能坐飞机111次的情况下,最优方案是从城市000直接飞到城市333,总耗时为1+7+4=121 + 7 + 4 = 121+7+4=12

数据规模

  • 对于10%10\%10%的数据,k=1k = 1k=1n≤200n \le 200n200
  • 对于30%30\%30%的数据,k=1k = 1k=1n≤100,000n \le 100,000n100,000
  • 对于另外40%40\%40%的数据,k≤100k \le 100k100n≤1,000n \le 1,000n1,000
  • 对于100%100\%100%的数据,k≤1,000k \le 1,000k1,000n≤100,000n \le 100,000n100,000k≤nk \le nkn,且1≤gi,fi≤100,0001 \le g_i, f_i \le 100,0001gi,fi100,000

大家可以自己写一写
下面给大家几个样例大家可以自己测试一下

输入:20 0
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999 99999
输出:120

输入:20 20
1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
输出:210

输入:20 1
500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500
2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1
输出:86

输入:20 5
20 100 20 100 20 100 20 100 20 100 20 100 20 100 20 100 20 100 20 100
100 1 100 2 100 3 100 4 100 5 100 6 100 7 100 8 100 9 100 10
输出:35

输入:20 3
100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
输出:20

输入:20 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
输出:20

输入:20 15
50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1
输出:72


这道题用dp[t][i]\mathit{dp}[t][i]dp[t][i]表示乘坐ttt次飞机到第iii座城市所花费的最短时间。(重点)

dp[t][i]\mathit{dp}[t][i]dp[t][i]可以分两种情况讨论:

1、从第i−1i-1i1座城市到第iii座是坐高铁的,那么此时到第i−1i-1i1座城市的坐飞机次数和到第iii座城市时相等,即
dp[i][t]=dp[i−1][t]+g[i−1]\mathit{dp}[i][t] = \mathit{dp}[i-1][t] + g[i-1]dp[i][t]=dp[i1][t]+g[i1]

2、Dr.X也有可能是从第jjj座城市连续坐飞机来第iii座城市的,这次连续的飞机算一次坐飞机机会并且耗时为各航线飞行时间之和。我们为了知道第jjj座城市到第iii座城市的时间之和,可以用前缀和。设s[i]=s[i]=s[i]=第0座城市到第iii座连续坐飞机所需要的时间之和。那么第jjj座城市到第iii座城市的时间之和就是(s[i]−s[j])(s[i]-s[j])(s[i]s[j]),所以

dp[i][t]=min⁡0≤j<i{dp[j][t−1]+s[i]−s[j]}\mathit{dp}[i][t] = \min_{0\le j < i}\big\{ \mathit{dp}[j][t-1] + s[i] - s[j] \big\}dp[i][t]=0j<imin{dp[j][t1]+s[i]s[j]}

提取s[i]s[i]s[i]得:
dp[i][t]=(min⁡0≤j<i(dp[j][t−1]−s[j]))+s[i]\mathit{dp}[i][t] = \bigg(\min_{0\le j < i} \big(\mathit{dp}[j][t-1] - s[j]\big)\bigg) + s[i]dp[i][t]=(0j<imin(dp[j][t1]s[j]))+s[i]

献代码:

#include<bits/stdc++.h>usingnamespacestd;longlongn,k;longlongg[100005],f[100005],s[100005];longlongdp[100005][1005];intmain(){ios::sync_with_stdio(0);cin.tie(0);cin>>n>>k;for(inti=0;i<n;i++)cin>>g[i];for(inti=0;i<n;i++)cin>>f[i];// 预处理飞行前缀和 ss[0]=0;for(inti=1;i<=n;i++){s[i]=s[i-1]+f[i-1];}// 初始化,边界:t=0,0次飞机,全程高铁dp[0][0]=0;for(inti=1;i<=n;i++){dp[i][0]=dp[i-1][0]+g[i-1];}// 枚举飞机使用次数 tfor(intt=1;t<=k;t++){longlongmin_val=dp[0][t-1]-s[0];for(inti=1;i<=n;i++){// 转移1:上一个城市坐高铁过来dp[i][t]=dp[i-1][t]+g[i-1];// 转移2:从前面某个j坐飞机直达idp[i][t]=min(dp[i][t],min_val+s[i]);// 更新最小值,当前i作为后续的jlonglongnow=dp[i][t-1]-s[i];if(now<min_val)min_val=now;}}// 答案:0~k次飞机取最小longlongans=1e18;for(intt=0;t<=k;t++){ans=min(ans,dp[n][t]);}cout<<ans;return0;}

若代码有何不妥之处请大佬们在评论区指点。感谢大家的浏览

http://www.jsqmd.com/news/1266966/

相关文章:

  • 信阳黄金回收实测:2家正规门店全城覆盖,附行情与避坑 - 观金堂黄金回收
  • C55x DSP上LMS自适应滤波与卷积编码的指令级优化实战
  • 出口退税选生产还是外贸身份 | 4个判断维度 - 欢欢在创业
  • 谷歌云TPU服务:AI加速芯片原理、应用场景与成本优化指南
  • 10分钟上手use-methods:构建高效React计数器应用的终极教程
  • Pygame游戏开发:Rect碰撞检测原理、优化与实战指南
  • NeuS2代码架构详解:从CUDA加速到增量训练策略的实现细节
  • bark-voice-cloning-HuBERT-quantizer项目概览:核心功能与技术原理解析
  • 深入解析SSI同步串行接口:架构、帧格式与实战配置
  • cyberdog_ros2核心功能揭秘:多模态感知与自主决策实现原理
  • 终极抖音批量下载工具:5分钟配置,一键保存无水印视频与音乐
  • 每天节省2.8小时!AI驱动的行业资讯动态追踪系统(含RSS/News API/Arxiv/GitHub多源融合方案)
  • Coordino安全配置:保护你的问答平台免受常见攻击
  • 同样的航班别人更便宜?学会怎么买特价机票,你也能订到低价票 - 工具软件使用方法推荐
  • 2026武汉正规防水补漏公司推荐:武汉宅安居漏水维修十二年专注武汉本地高层卫生间漏水维修,无转包、无分包-精准测漏和纳米技术-口碑优质 - 天下观知
  • R3nzSkin:英雄联盟皮肤修改器的终极技术解析与实战指南
  • 烟台黄金回收实测:2家正规门店全城覆盖,附避坑指南 - 观金堂黄金回收
  • C++ 中 shared ptr 详解:原理与线程安全性分析
  • CentOS系统初始化与安全加固全攻略
  • JavaQuestPlayer:跨平台QSP游戏运行工具的设计原理与实战指南
  • AI技术两极分化下云企成本优化与差异化竞争策略
  • 基于DNS协议的AI工具发现机制:原理、实现与应用
  • 广州名表回收怎么选?实体门店 + 全城上门,老牌连锁更安心 - 易奢福
  • 【AI自动化数据入库终极指南】:20年DBA亲授5大避坑法则与实时入库提速300%的实战秘钥
  • 雅安黄金回收实测:2家正规店全城覆盖,附避坑指南 - 观金堂黄金回收
  • 机器学习在校园心理健康预警系统中的应用实践
  • 市面上具备充足生产产能的靠谱全棉纱卡制造厂哪家专业 - 速递信息
  • 文本分块技术在RAG系统中的4种实战策略
  • 老客户流失快的代账公司找企跑星补哪一环|三个环节与补法 - 欢欢在创业
  • 基于.NET MAUI与YOLOv5的跨平台实时目标检测实践