NO.82十六届蓝桥杯备战|动态规划-从记忆化搜索到动态规划|下楼梯|数字三角形(C++)

news2025/4/12 16:47:56
  1. 记忆化搜索
    在搜索的过程中,如果搜索树中有很多重复的结点,此时可以通过⼀个"备忘录",记录第⼀次搜索到的结果。当下⼀次搜索到这个结点时,直接在"备忘录"⾥⾯找结果。其中,搜索树中的⼀个⼀个结点,也称为⼀个⼀个状态。
    ⽐如经典的斐波那契数列问题
int f[N]; // 备忘录  

int fib(int n)  
{  
	// 搜索之前先往备忘录⾥⾯瞅瞅  
	if(f[n] != -1) return f[n];  
	if(n == 0 || n == 1) return f[n] = n;  
	
	// 返回之前,把结果记录在备忘录中  
	f[n] = fib(n - 1) + fib(n - 2);  
	return f[n];  
}
  1. 递归改递推
    在⽤记忆化搜索解决斐波那契问题时,如果关注"备忘录"的填写过程,会发现它是从左往右依次填写的。当i位置前⾯的格⼦填写完毕之后,就可以根据格⼦⾥⾯的值计算出i位置的值。所以,整个递归过程,我们也可以改写成循环的形式,也就是递推
int f[N]; // f[i] 表⽰:第 i 个斐波那契数  
int fib(int n)  
{  
	// 初始化前两个格⼦  
	f[0] = 0; f[1] = 1;  
	
	// 按照递推公式计算后⾯的值  
	for(int i = 2; i <= n; i++)  
	{  
		f[i] = f[i - 1] + f[i - 2];  
	}  
	
	// 返回结果  
	return f[n];  
}
  1. 动态规划
    动态规划(Dynamic Programming,简称DP)是⼀种⽤于解决多阶段决策问题的算法思想。它通过将复杂问题分解为更⼩的⼦问题,并存储⼦问题的解(通常称为“状态”),从⽽避免重复计算,提⾼效率。因此,动态规划⾥,蕴含着分治与剪枝思想。
    上述通过记忆化搜索以及递推解决斐波那契数列的⽅式,其实都是动态规划。
    注意:
  • 动态规划中的相关概念其实远不⽌如此,还会有:重叠⼦问题、最优⼦结构、⽆后效性、有向⽆环图等等。
  • 这些概念没有⼀段时间的沉淀是不可能完全理解的。可以等学过⼀段时间之后,再去接触这些概念。不过,这些概念即使不懂,也不影响做题~
    在递推形式的动态规划中,常⽤下⾯的专有名词来表述:
  1. 状态表⽰:指 f 数组中,每⼀个格⼦代表的含义。其中,这个数组也会称为 dp 数组,或者dp 表。
  2. 状态转移⽅程:指 f 数组中,每⼀个格⼦是如何⽤其余的格⼦推导出来的
  3. 初始化:在填表之前,根据题⽬中的默认条件或者问题的默认初始状态,将 f 数组中若⼲格⼦先填上值。
    其实递推形式的动态规划中的各种表述,是可以对应到递归形式的:
  • 状态表⽰<—>递归函数的意义;
  • 状态转移⽅程<—>递归函数的主函数体;
  • 初始化<—>递归函数的递归出⼝。
  1. 如何利⽤动态规划解决问题
    第⼀种⽅式当然就是记忆化搜索了:
  • 先⽤递归的思想去解决问题;
  • 如果有重复⼦问题,就改成记忆化搜索的形式。
    第⼆种⽅式,直接使⽤递推形式的动态规划解决:
  1. 定义状态表⽰:
    ⼀般情况下根据经验+递归函数的意义,赋予 dp 数组相应的含义。(其实还可以去蒙⼀个,如果蒙的状态表⽰能解决问题,说明蒙对了。如果蒙错了,再换⼀个试~)
  2. 推导状态转移⽅程:
    根据状态表⽰以及题意,在 dp 表中分析,当前格⼦如何通过其余格⼦推导出来。
  3. 初始化:
    根据题意,先将显⽽易⻅的以及边界情况下的位置填上值。
  4. 确定填表顺序:
    根据状态转移⽅程,确定按照什么顺序来填表。
  5. 确定最终结果:
    根据题意,在表中找出最终结果
P10250 [GESP样题 六级] 下楼梯 - 洛谷

因为上楼和下楼是⼀个可逆的过程,因此我们可以把下楼问题转化成上到第n个台阶,⼀共有多少种⽅案。
解法:动态规划

  1. 状态表⽰:
    dp[i] 表⽰:⾛到第i 个台阶的总⽅案数。
    那最终结果就是在dp[n]处取到。
  2. 状态转移⽅程:
    根据最后⼀步划分问题,⾛到第i 个台阶的⽅式有三种:
    a. 从i - 1 台阶向上⾛1 个台阶,此时⾛到i 台阶的⽅案就是dp[i - 1]
    b. 从i - 2 台阶向上⾛2 个台阶,此时⾛到i 台阶的⽅案就是dp[i - 2]
    c. 从i - 3 台阶向上⾛3 个台阶,此时⾛到i 台阶的⽅案就是dp[i - 3]
    综上所述,dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
  3. 初始化:
    填i位置的值时,⾄少需要前三个位置的值,因此需要初始化dp[0] = 1, dp[1] = 1, dp[2] = 2,然后从i = 3开始填。
    或者初始化dp[1] = 1, dp[2] = 2, dp[3] = 4,然后从i = 4 开始填。
  4. 填表顺序:
    明显是从左往右
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 65;

int n;
LL f[N]; //f[i]表示有i个台阶的时候,一共有多少种方案

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;

    //初始化
    f[0] = 1; f[1] = 1; f[2] = 2;

    for (int i = 3; i <= n; i++)
    {
        f[i] = f[i - 1] + f[i - 2] + f[i - 3];       
    }

    cout << f[n] << endl;
    
    return 0;
}

动态规划的空间优化:
我们发现,在填写dp[i]的值时,我们仅仅需要前三个格⼦的值,第i-4个及其之前的格⼦的值已经毫⽆⽤处了。因此,可以⽤三个变量记录i位置之前三个格⼦的值,然后在填完i位置的值之
后,滚动向后更新
![[Pasted image 20250409153812.png]]

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 65;

int n;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;

    LL a = 1, b = 1, c = 2;

    for (int i = 3; i <= n; i++)
    {
        LL t = a + b + c;
        a = b;
        b = c;
        c = t;
    }

    if (n == 1) cout << b << endl;
    else cout << c << endl;
    
    return 0;
}
P1216 [IOI 1994] 数字三角形 Number Triangles - 洛谷

![[Pasted image 20250409160024.png]]

学习动态规划最经典的⼊⻔题。
解法:动态规划

  1. 状态表⽰:
    dp[i][j] 表⽰:⾛到[i, j] 位置的最⼤权值。
    那最终结果就是在dp 表的第n ⾏中,所有元素的最⼤值。
  2. 状态转移⽅程:
    根据最后⼀步划分问题,⾛到[i, j] 位置的⽅式有两种:
    a. 从[i - 1, j] 位置向下⾛⼀格,此时⾛到[i, j] 位置的最⼤权值就是dp[i - 1][j]
    b. 从[i - 1, j - 1]位置向右下⾛⼀格,此时⾛到[i, j] 位置的最⼤权值就是dp[i - 1][j - 1]
    综上所述,应该是两种情况的最⼤值再加上[i,j]位置的权值:
    dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + a[i][j]
  3. 初始化:
    因为dp 表被0 包围着,并不影响我们的最终结果,因此可以直接填表。
    思考,如果权值出现负数的话,需不需要初始化?
    ◦ 此时可以全都初始化为 − ∞ -\infty ,负⽆穷⼤在取max 之后,并不影响最终结果。
  4. 填表顺序:
    从左往右填写每⼀⾏,每⼀⾏从左往右
#include <bits/stdc++.h>
using namespace std;

const int N = 1010;

int n;
int a[N][N];
int f[N][N]; //f[i][j]表示从1,1走到i,j的时候,所有方案数的最大权值

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= i; j++)
            cin >> a[i][j];

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= i; j++)
        {
            f[i][j] = max(f[i-1][j], f[i-1][j-1]) + a[i][j];    
        }
    }

    int ret = 0;
    for (int j = 1; j <= n; j++)
    {
        ret = max(ret, f[n][j]);        
    }
    cout << ret << endl;
    
    return 0;
}

动态规划的空间优化:
我们发现,在填写第i ⾏的值时,我们仅仅需要前⼀⾏的值,并不需要第i - 2 以及之前⾏的值。
因此,我们可以只⽤⼀个⼀维数组来记录上⼀⾏的结果,然后在这个数组上更新当前⾏的值
![[Pasted image 20250409161744.png]]

需要注意,当⽤因为我们当前这个位置的值需要左上⻆位置的值,因此滚动数组优化的时候,要改变第⼆维的遍历顺序

#include <bits/stdc++.h>
using namespace std;

const int N = 1010;

int n;
int a[N][N];
int f[N]; //f[i][j]表示从1,1走到i,j的时候,所有方案数的最大权值

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= i; j++)
            cin >> a[i][j];

    for (int i = 1; i <= n; i++)
    {
        for (int j = i; j >= 1; j--)
        {
            f[j] = max(f[j], f[j-1]) + a[i][j];    
        }
    }

    int ret = 0;
    for (int j = 1; j <= n; j++)
    {
        ret = max(ret, f[j]);        
    }
    cout << ret << endl;
    
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【时时三省】(C语言基础)用switch语句实现多分支选择结构 例题

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 例题&#xff1a; 用switch语句处理菜单命令。在许多应用程序中&#xff0c;用菜单对流程进行控制&#xff0c;例如从键盘输入一个 A 或 a 字符&#xff0c;就会执行A操作&#xff0c;输入一…

全域数字化:从“智慧城市”到“数字生命体”的进化之路

一、国家战略下的城市数字化浪潮 2024年5月&#xff0c;国家四部委联合发布《关于深化智慧城市发展 推进城市全域数字化转型的指导意见》&#xff0c;明确提出以数据为引擎&#xff0c;系统性重塑城市技术架构与管理流程&#xff0c;推动城市治理迈向“全域协同、数实融合”的…

基于SSM的线上花店鲜花销售商城网站系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

DAPP实战篇:使用web3.js连接合约

说明 本系列内容目录:专栏:区块链入门到放弃查看目录 如果你还没有创建好项目请先查看:《DApp实战篇:先用前端起个项目》,如果你还不知道web3.js是什么请先查看:《DApp实战篇:前端技术栈一览》。 安装 点此查看web3.js官方文档 打开项目根目录,并唤起终端: 键入w…

K8S-证书过期更新

K8S证书过期问题 K8S证书过期处理方法 Unable to connect to the server: x509: certificate has expired or is not yet valid 1、查看证书有效期&#xff1a; # kubeadm certs check-expiration2、备份证书 # cp -rp /etc/kubernetes /etc/kubernetes.bak3、直接重建证书 …

蓝桥杯第十五届真题——握手问题

#include<bits/stdc.h> using namespace std; int main() {ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int sum0;for(int i7;i<49;i){sumi;}cout<<sum;return 0; }

5G_WiFi_CE_DFS

目录 一、规范要求 1、法规目录 2、定义 3、运行模式 4、主/从设备相关的运行行为及具体的动态频率选择&#xff08;DFS&#xff09;要求 5、产品角色确定测试项目 6、测试项目 测试项1&#xff1a;信道可用性检查&#xff08;Channel Availability Check&#xff09; …

springboot 处理编码的格式为opus的音频数据解决方案【java8】

opus编码的格式概念&#xff1a; Opus是一个有损声音编码的格式&#xff0c;由Xiph.Org基金会开发&#xff0c;之后由IETF&#xff08;互联网工程任务组&#xff09;进行标准化&#xff0c;目标是希望用单一格式包含声音和语音&#xff0c;取代Speex和Vorbis&#xff0c;且适用…

RK3568 基于Gstreamer的多媒体调试记录

文章目录 1、环境介绍2、概念理清3、提前准备4、GStreamer编译5、GStreamer基础介绍6、视频播放初体验7、视频硬编码7.1、h2647.2、h265 8、视频硬解码8.1、解码视频并播放8.2、解码视频并播放带音频 1、环境介绍 硬件&#xff1a;飞凌ok3568-c开发板 软件&#xff1a;原厂rk…

VS Code 的 .S 汇编文件里面的注释不显示绿色

1. 确认文件语言模式 打开 .S 文件后&#xff0c;查看 VS Code 右下角的状态栏&#xff0c;确认当前文件的识别模式&#xff08;如 Assembly、Plain Text 等&#xff09;。如果显示为 Plain Text 或其他非汇编模式&#xff1a; 点击状态栏中的语言模式&#xff08;如 Plain Te…

5分钟读懂ArgoCD:在Kubernetes中实现持续部署

Kubernetes中的Argo CD介绍 Argo CD是用于Kubernetes的声明式GitOps持续交付工具。它遵循GitOps模式&#xff0c;以Git仓库作为定义所需应用程序状态的唯一真实来源&#xff0c;能在指定的目标环境中自动部署应用程序&#xff0c;并持续监控应用程序的运行状态&#xff0c;确保…

cs224w课程学习笔记-第10课

cs224w课程学习笔记-第10课 异构图 前言一、异构图1、异构图定义2、异构图与同构图 二、异构图下的GNN1、GCN扩展至RGCN1.1 RGCN原理1.2 异构图的任务预测特点1.3 异构图任务预测基础案例 2、完整的异构图GCN三、异构图下的Transformer 前言 异构图的定义是节点内部存在类型不…

OpenCV 图形API(26)图像滤波-----方框滤波函数boxFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 使用方框滤波器模糊图像。 该函数使用以下内核来平滑图像&#xff1a; K α [ 1 1 … 1 1 1 … 1 ⋮ ⋮ ⋱ ⋮ 1 1 … 1 ] K \alpha \begin{b…

大模型上下文协议MCP详解(2)—核心功能

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. 标准化上下文交互技术 1.1 实时数据接入能力 MCP(Model Context Protocol)通过标准化的接口,为 AI 模型提供了强大的实时数据接入能力,使其能够快速获取和处理来自不同数据源的实时信息。…

剑指Offer(数据结构与算法面试题精讲)C++版——day8

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day8 题目一&#xff1a;链表中环的入口节点题目二&#xff1a;两个链表的第1个重合节点题目三&#xff1a;反转链表附录&#xff1a;源码gitee仓库 题目一&#xff1a;链表中环的入口节点 这道题的有如下三个…

【Qt】QxOrm:下载、安装、使用

1、下载源码 github地址:https://github.com/QxOrm/QxOrm 稳定版本下载:https://github.com/QxOrm/QxOrm/releases/tag/1.5.0 2、编译源码 QxOrm支持cmake编译(CMakeLists.txt)、Qt pro工程编译(QxOrm.pro) 以 QxOrm.pro 为例,编译生成的库,没有在 build-QxOrm-1.5…

CISCO组建RIP V2路由网络

1.实验准备&#xff1a; 2.具体配置&#xff1a; 2.1根据分配好的IP地址配置静态IP&#xff1a; 2.1.1PC配置&#xff1a; PC0&#xff1a; PC1&#xff1a; PC2&#xff1a; 2.1.2路由器配置&#xff1a; R0&#xff1a; Router>en Router#conf t Enter configuration…

【数学建模】(智能优化算法)鲸鱼优化算法(Whale Optimization Algorithm)详解与应用

鲸鱼优化算法(Whale Optimization Algorithm)详解与应用 文章目录 鲸鱼优化算法(Whale Optimization Algorithm)详解与应用1. 引言2. 算法原理2.1 生物学基础2.2 数学模型[^3]1. 包围猎物阶段2. 气泡网攻击&#xff08;螺旋更新&#xff09;3. 随机搜索猎物&#xff08;全局探索…

【深度洞察】解码饮料行业破局点:场景革命

当东鹏特饮以 “大瓶装 防尘盖” 精准解决货车司机的场景化需求&#xff0c;当农夫山泉通过 “冷藏版东方树叶” 打开年轻白领的早餐场景 —— 这些现象级案例背后&#xff0c;是饮料行业底层逻辑的深刻变革&#xff1a;真正的市场增量&#xff0c;藏在对消费场景的极致拆解中…

工业科学级天文相机:跨界融合的高精密成像解决方案

随着国内科技的快速发展&#xff0c;工业相机领域正悄然兴起一场"天文级"的技术革命。这类兼具工业设备可靠性与天文观测精度的特殊相机&#xff0c;正在半导体制造、天文观测、空间探测等领域开辟新的应用疆域。其核心技术突破不仅体现在传感器性能的提升&#xff0…