动态规划 dp 题目与讲解

蓝桥动态规划(dp)题目讲解 动态规划(dp)一直都是蓝桥杯等算法比赛常常要考的知识点,借助这个机会,我把我的一些看法(比较初级)分享给大家。dp的题比较重要的就是定义,初始化和状态转移方程。我们直接上例子。 阅读详情

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



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

题目描述

Dr. X 想从城市 000 出发前往城市 nnn。对于所有满足 0≤i≤n−10 \le i \le n - 10≤i≤n−1 的整数 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 1j≥1),总飞行时间等于途经各段航线的飞行时间之和 fi+fi+1+⋯+fi+j−1,\begin{aligned} f_i + f_{i+1} + \cdots + f_{i+j-1}, \end{aligned}fi​+fi+1​+⋯+fi+j−1​,​ 但这样一次连续飞行 只算乘坐一次飞机。请计算 Dr. X 从城市 000 出发到达城市 nnn 所需的最少时间。

输入格式

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

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

第三行包含 nnn 个空格分隔的整数 f0,f1,…,fn−1f_0, f_1, \ldots, f_{n-1}f0​,f1​,…,fn−1​,其中 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=1,n≤200n \le 200n≤200。
  • 对于 30%30\%30% 的数据,k=1k = 1k=1,n≤100,000n \le 100,000n≤100,000。
  • 对于另外 40%40\%40% 的数据,k≤100k \le 100k≤100,n≤1,000n \le 1,000n≤1,000。
  • 对于 100%100\%100% 的数据,k≤1,000k \le 1,000k≤1,000,n≤100,000n \le 100,000n≤100,000,k≤nk \le nk≤n,且 1≤gi,fi≤100,0001 \le g_i, f_i \le 100,0001≤gi​,fi​≤100,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-1i−1 座城市到第 iii 座是坐高铁的,那么此时到第 i−1i-1i−1 座城市的坐飞机次数和到第 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[i−1][t]+g[i−1]

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]=0≤j<imin​{dp[j][t−1]+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]=(0≤j<imin​(dp[j][t−1]−s[j]))+s[i]

献代码:

#include<bits/stdc++.h>
using namespace std;
long long n,k;
long long g[100005],f[100005],s[100005];
long long dp[100005][1005]; 
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    cin>>n>>k;
    for(int i=0;i<n;i++) cin>>g[i];
    for(int i=0;i<n;i++) cin>>f[i];

    // 预处理飞行前缀和 s
    s[0] = 0;
    for(int i=1;i<=n;i++){
        s[i] = s[i-1] + f[i-1];
    }

    // 初始化,边界:t=0,0次飞机,全程高铁
    dp[0][0] = 0;
    for(int i=1;i<=n;i++){
        dp[i][0] = dp[i-1][0] + g[i-1];
    }

    // 枚举飞机使用次数 t
    for(int t=1;t<=k;t++){
        long long min_val = dp[0][t-1] - s[0];
        for(int i=1;i<=n;i++){
            // 转移1:上一个城市坐高铁过来
            dp[i][t] = dp[i-1][t] + g[i-1];
            // 转移2:从前面某个j坐飞机直达i
            dp[i][t] = min(dp[i][t], min_val + s[i]);
            // 更新最小值,当前i作为后续的j
            long long now = dp[i][t-1] - s[i];
            if(now < min_val) min_val = now;
        }
    }

    // 答案:0~k次飞机取最小
    long long ans = 1e18;
    for(int t=0;t<=k;t++){
        ans = min(ans, dp[n][t]);
    }
    cout<<ans;
    return 0;
}

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

leetcode 经典动态规划DP算法题目(思路、方法、code) leetcode 经典动态规划DP算法题目(思路、方法、code) 动态规划最重要的在于设计DP数组,找到相应的动态转移方程 文章目录leetcode 经典动态规划DP算法题目(思路、方法、code)[70. 爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/)[198. 打家劫舍](https://leetcode-cn.com/problems/house-robber/)[213. 打家劫舍 II](https://leetcode-cn.co 阅读详情

相关推荐

闫式DP分析法

学好DP的一个关键点在于刷遍所有类型的DP题目 选择DP问题:背包模型 序列DP问题 状态压缩问题 状态机问题 树形DP问题 区间DP问题 斜率优化问题 文章目录1. 核心思想——集合2. 01背包问题2.1 集合2.2 属性2.3 状态计算 1. 核心思想——集合 闫式DP分析法的核心思想是从集合的角度来分析DP问题。 所有的DP问题都可以使用闫式DP分析法进行分析。(经过70道题目验证通过????) 我们可以把做过的所有DP问题都看作是有限集上的最值问题。 DP问题 == 有限集上的最值

yc_cy1999的博客 3110

动态规划 dp算法

此处以求最小值为例✅ 状态定义:dp[i][j] = 将区间 [i,j] 合并成一段的最小代价✅ 转移方程:对于每个断点k,尝试将区间[i,j]分割成[i,k],[k+1,j]两端进行合并,则dp[i][j] = 区间[i,j]经过某种构造操作后的最大值(最小值)✅ 状态定义:dp[i][j] 表示将区间 [i,j] 转化为合法结构(如合法括号、回文)的最小代价(如删除次数)✅ 转移方程:情况1 s[i]==s[j] dp[i][j]=dp[i+1][j-1]情况2 s[i]!

scsdvsvf的博客 1200

<蓝桥杯软件赛>零基础备赛20周--第18周--动态规划初步

DP初步

罗勇军的博客 8759

【算法基础】动态规划[二]——线性&区间DP(闫氏DP分析法)

一、线性DP 1、AcWing 898. 数字三角形 算法 1 算法2 2、AcWing895. 最长上升子序列 [DP] 3、AcWing 897. 最长公共子序列 4、最短编辑距离 5、编辑距离 二、区间DP AcWing 282. 石子合并

Remember who you are! 1814

《Hadoop大数据技术原理与应用》(第2版)黑马程序员的课后习题答案

《Hadoop大数据技术原理与应用》(第2版)黑马程序员的课后习题答案

qq_36773158的博客 4646

学习STM32的无人机控制

下面是一个基于STM32的无人机控制的简单示例代码,包括四旋翼的PID控制、遥控器信号解析和电机控制。本示例以STM32F103系列为例,使用Keil C编译器进行开发。

qq_67153941的博客 706

猿创征文 |【算法面试入门必刷】动态规划-线性dp(一)

【算法面试入门必刷】动态规划-线性dp篇(一) 📦个人主页:一二三o-0-O的博客 🏆技术方向:C/C++客户端资深工程师(直播+音视频剪辑) 👨‍💻作者简介:数据结构算法与音视频领域创作者 📒 系列专栏:牛客网面试必刷 📣专栏目标:帮助伙伴们通过系统训练,掌握数据结构与算法,收获心仪Offer 📝推荐一个找工作神器:牛客刷题网 【面试经验|实习招聘内推,求职就业一战解决】 🧡如果对您有帮助的话,欢迎点赞👍收藏📂,关注不迷路...

MichaelKongChina的博客 2219

在Mac上搭建本地AI工作流:Dify与DeepSeek的完美结合

本文介绍了在Mac上搭建本地AI工作流的方法,结合Dify平台和DeepSeek模型。Dify是一个开源的大语言模型应用开发平台,支持可视化AI应用开发。部署步骤包括:1)安装Homebrew和Docker;2)克隆Dify代码库;3)配置环境变量并启动服务。同时,使用Ollama工具本地部署DeepSeek模型,将其集成到Dify中创建聊天助手。通过配置模型接口和新建应用,用户可以在本地环境中实现AI对话功能。这种方案既保证了数据隐私,又提供了灵活的AI应用开发能力。

Linda的自动化测试之旅 1535

AtCoder DP Contest 题目全讲(上)

洛谷题单(非本人整理)有一些好写的题就不贴代码了,细节较多的再放上。本篇文章为上期(收录题目A–>NA–>N),题目较为基础,进阶题目放在下期讲解(目前还在咕咕咕)。A题非常简单的方程。fimin⁡fi−1∣hi−hi−1∣fi−2∣hi−hi−2∣fi​minfi−1​∣hi​−hi−1​∣fi−2​∣hi​−hi−2​∣,递推一下就行了。B题。

summ1ts的博客 1537

优化点列图(RMS半径)的操作数

优化点列图(RMS半径)的操作数

weixin_72050316的博客 2256

【微服务】SpringBoot 整合 FastExcel 实现导入导出操作详解

SpringBoot 整合 FastExcel 实现导入导出操作详解

congge 4233

动态规划总结——线性DP(1)(基于LeetCode题目)

LeetCode dp问题汇总 1.线性DP class Solution { public int longestCommonSubsequence(String text1, String text2) { int[] dp= new int[text1.length()+1]; for(int j=0;j<text2.length();j++)...

qq_38732834的博客 526

100天精通Python(进阶篇)——第43天:批量将PDF转Word文档(附上脚本代码)

100天精通Python(进阶篇)——第43天:批量将PDF转Word文档(附上脚本代码)

努力让自己发光,对的人才能迎着光而来 9万+

动态规划之打家劫舍

最后在此,送坚持到这里的读者一句话。简单题,用来培养方法;难题,用来突破自我;两者结合,方能突破至高;当难题,难得你受不了时,恰恰是因为你没有重视简单题!希望大家有所收获。

2302_80067378的博客 1955

2021-09-29 每天几个LCEDA小知识——如何交叉选择并阵列放置元器件

立创EDA专业版之交叉选择并阵列放置元器件????交叉选择????阵列放置 ????交叉选择 在原理图界面,先框选需要交叉选择的元器件对象,右键,选择交叉选择(如果熟练之后,直接选择元器件,快捷键Shift+X)。 完成上述操作之后,可以看到自动跳转到PCB绘图界面,并自动选定PCB中相关的元器件,接下来不要取消选择的状态,在相关元器件被选中的情况下,即可开展阵列放置,将这些元器件都放在一个区域,方便PCB画线前的布局工作。 ????阵列放置 在布局菜单栏中,选择分布,选择阵列分布, 在弹出的对话框

l64481000的博客 1463

8.26华为OD机试真题 新系统 - 字符串回文判 (Java/Py/C/C++/Js/Go)

8.26华为OD机试真题 新系统 - 字符串回文判 (Java/Py/C/C++/Js/Go)

算法大师! 1230

代码随想录 动态规划-基础题目

从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。这里要看一下递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。所以递推公式:dp[i] += dp[j - 1] * dp[i - j];

m0_74267125的博客 1089

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

动态规划分类题目总结

动态规划分类有很多划分方法,网上有很多是按照状态来分,分为一维、二维、区间、树形等等。我觉得还是按功能即解决的问题的类型以及难易程度来分比较好,下面按照我自己的理解和归纳,把动态规划的分类如下: 一、简单基础dp 这类dp主要是一些状态比较容易表示,转移方程比较好想,问题比较基本常见的。主要包括递推、背包、LIS(最长递增序列),LCS(最长公共子序列),下面针对这几种类型,推荐一下比较好的学...

逐梦者 714

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

DP总结

线性动态规划 背包问题 01背包 0-1背包:给定n个物品,每个物品有一个重量,一个价值,背包容量为v,物品不能拆开,求最多能获得的价值。 分析: 我们设f[i,j]表示前i件物品占据j的容量时物品的最大价值,那么f[i,j]=max(f[i,j],f[i-1,j-v[i]),我们发现第一维状态是可以省略的,也就是缩为f[i]表示占据容量为i时的最大价值,这个值要从大到小枚举求解,否则就会出现一个...

子衿君的博客 547

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

算法学习记录:动态规划

算法学习记录不是算法介绍,本文记录的是从零开始的学习过程(见到的例题,代码的理解……),所有内容按学习顺序更新,而且不保证正确,如有错误,请帮助指出。学习工具:蓝桥OJ,LeetCode。

d3535的博客 1749

与树相关的题目 树形DP 总结,不断汇总中

hdu 1561     The more, The Better   树形DP入门   利用分组背包的思想 #include #include #include using namespace std; int dp[250][250]; vector edge[250]; int n,m; int val[250]; int max(int a,int b){ ret

努力奋斗才能梦想成真 1116

动态规划(3)——二维dp

欢迎来到博主的专栏:算法解析博主ID:代码小豪。

2301_77239666的博客 1044

代码随想录day43-最长递增子序列/最长连续递增序列/最长重复子数组

dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j](这样不需要初始化)。当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1。dp数组代表i之前包括i的以nums[i]结尾的最长递增子序列的长度,全部初始化为1。每次循环都要从一开始递归到当前数字之前。674. 最长连续递增序列。718. 最长重复子数组。

zhengjojo的博客 278

【5】区间类型动态规划学习笔记

教练阳了,这次上的是录播课(悲希望教练早点好起来。

WSD3319_的博客 1937

算法:动态规划题目总结

动态规划题目总结

晶晶的博客 150

动态规划DP思想总结

记录下每个小问题的最优解,并根据这些小问题的最优解,推导出更大问题的最优解,最终得到原始问题的答案。

falldeep的算法世界 976
上一篇: CCF-GESP C++ 1-5级考纲完全指南
下一篇: c++入门教程4:条件分支与判断语句
user_4
博客等级 码龄112天 85粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值