(蓝桥杯C/C++)——动态规划(DP)

目录

一、线性DP

1.DP(动态规划)简介

2.动态规划的分析步骤

3.例题讲解

二、二维DP

1.二维DP简介

2.选数异或

三、最长上升子序列LIS

1.LIS简介

2.例题讲解

四、最长公共子序列LCS

1.最长公共子序列

2.最长公共子序列

2.求出具体子序列


一、线性DP

1.DP(动态规划)简介

DP(动态规划)全称DynamicProgramming,是运筹学的一个分支,是一种将复杂问题分解成很多重叠的子问题,并通过子问题的解得到整个问题的解的算法。

在动态规划中有一些概念:
状态:就是形如dp[il[il=val的取值,其中i,i为下标,也是用于描述、确定状态所需的变量,val为状态值。
状态转移:状态与状态之间的转移关系,一般可以表示为一个数学表达式,转移方向决迭代或递归方向。
最终状态:也就是题目所求的状态,最后的答案。

2.动态规划的分析步骤

1.确定状态,一般为“到第i个为止,xx为j(xx为k)的方案数/最小代价/最大价值”,可以根据数据范围和复杂度来推理。

2.确定状态转移方程,即从已知状态得到新状态的方法,并确保按照这个方向一定可以正确躾渥黨瘛得到最终状态。
根据状态转移的方向来决定使用迭代法还是递归法(记忆化)

3.确定最终状态并输出。

3.例题讲解

破损的楼梯
问题描述
小孟来到了一座高耸的楼梯前,楼梯共有N级台阶,从第0级台阶出发。小孟每次可以迈上1级或2级台阶,但是,楼梯上的a级、第02级、第 a1级,以此奔推。共 M 级台阶的台阶面已经坏了,不能上去。
现在,小孟想要到达楼梯的顶端,也就是第N级台阶,但他不能踩到坏了的台阶上。请问有多少种不踩到坏了的台阶上到达顶端的方案数?
由于方案数很大,请输出其对1e9+7取模的结果

例题分析

设状态dp[i]表示走到第i级台阶的方案数。
状态转移方程为dp[i]=dp[i-1]+dp[i-2],如
果i为破损的,则dp[il=0。
可以用一个桶来记录哪些位置是破损的。
从前往后更新,最后输出dp[n]。

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

const int N = 1e5+10,mod - 1e9+7;

int n,m,x,f[N],vis[N];

signed main()

{

     cin >> n >> m;

     for(int i=l;i<=m;i ++)

      {

        cin >> x;

        vis[x]= 1;

}
f[0]= 1;

for(int i - 1;i < -n; i++)

     {

        if(vis[i])

         continue;

         fi]-f[i -1+f[i - 2];

         f[i] %= mod;

  }
cout << f[n] << '\n';

return 0;

}

二、二维DP

1.二维DP简介

二维DP就是指dp数组的维度为二维的dp(当然有时候可能会三维四维,或者存在一些优化使得它降维成一维),广义的来讲就是有多个维度的dp,即用于描述dp状态的变量不止一个。

2.选数异或

给定n个正整数a[i],询问你其中有多少个不同子序列进行异或运算的值为x?
由于结果很大,你需要对998244353取模

异或运算:位远算的一种,符号为由,1^1=0,1^0=1,0^0=0.

子序列: 从切始序列中选出若于个数保持原有顺序的序列,

例题分析

设状态dp[i][j]表示到第i个数字为止(但不一定以第i个数字结尾),异或和为i的子序列个数。

对于第i层的状态,转移的方式有“选第i个”和“不选第i个”两种,转移方程为dp[i][j]= dp[i][j] + dp[i - 1]j ^ dp[i-1[j ^ a]]。
最后结果就是dp[n][x]。

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

using ll = long long;

const int N = 1e5+9;

const ll p = 998244353;

int a[N],dp[N][70];


int main()

{
    int n, x; cin >> n >> x;

   dp [0] [0 = 1;

   for(int i = 1; i <= n; ++ i)

    {

      for(int j = 0; j < 64; ++j)

       {
         dp[i][j] = (dp[i-1][j] + dp[i-1][j ^ a[i]]) % p;

        }

     }
cout << dp[n][m] << '\n';

return 0;

}

三、最长上升子序列LIS

1.LIS简介

LIS(最长上升子序列)是一个经典的DP模型。
子序列指的是一个序列中,按照原顺序选出若干个不一定连续的元素所组成的序列。这节课我们讲解O(n^2)时间复杂度的朴素LIS模型,LIS还有一种利用二分实现的O(nlogn)时间复杂度的模型,大家可以自行去学习,理解起来略有难度。在求解LIS时,一般我们会设dp[i]表示1~i序列中以a[i]结尾的最长上升子序列的长度,状态转移方程为:
dp[i]= max(dp[j] + 1),

if a[i]> a[j]
表示a[i]要插入到不同子序列后面的情况。

a13425372
dp12324352

2.例题讲解

小明是蓝桥王国的勇士,他晋升为蓝桥骑士,于是决定不断突破自我
这天蓝桥首席骑士长给他安排了 N 个对手,他们的战力值分别为….a1,a2,···an,且按顺序挡在小明的前方,对于这些对手小明可以选择单挑也可以选择群战
作为热血豪放的勇士,小明从不走回头路,且只愿意挑战战力值越来越强的对手
请你算算小明最多会挑战多少名对手

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

const int N = 1e3+9;

int a[N],dp[N];

int main()

{

  int n;

  cin >> n;

 for(int i = 1;i <= n; ++i)

 cin >> a[i];

    for(int i = 1;i <= n; ++i)

    {

        dp[i] = 1;

         for(int j =1;j < i; ++j)

         {

           if(a[i] > a[j])

            dp[i] = max(dp[i], dp[j] + 1);

          }

    }

   int ans = 0;

   for (int i =1;i < n; ++i)

    ans = max(ans, dp[i]);

    cout << ans << '\n';

   return 0;

}

四、最长公共子序列LCS

1.最长公共子序列

LCS(Longest Common Subsequence 最长公共子序列)是一个经典的DP模型。
这节课我们讲解O(n^2)时间复杂度的LCS模型。
LCS问题是给定两个序列A和B,求它们的最长公共子序列。

在求解LCS时,一般我们会设dp[i][j]表示A[1~i]序列和B[1~j]序列中(不规定结尾)的最长公共子序列的长度,状态转移方程为:
if ali]=b[j]:dp{i][j]= dp{i-1][j-1]+1
else dp[i][j]= max(dp[i-1][jl, dp[i][j-1]);

解释一下:当ali]=b[j]时,可以将他们作为插入到LCS的后面,使得长度变长1,当a[i]!=b[说明此时LCS不会延长,那就要从dp[i-1][j]和dp[i][j-1]中取大的作为最长的长度。

a13425
b14352

dp12345
11111
211222
312222
412223
512233

132

2.最长公共子序列

给定一个长度为 N 数组 a 和一个长度为 M 的数组 b

请你求出它们的最长公共子序列长度为多少。

例题分析

设dp[i][j]表示序列a[1~i],b[1~j]中最长公共子序列长度,

状态转移方程为:

if ali]=b[j]:dp[i][j] = dp[i-1][j-1]+1
else: dp|i][j]= max(dp[i-1][j], dp[i][j-1]);最后输出dpln]lm]即可。

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

const int N = 1e3+9,

int n, m,a[N], b[N], dp[M][N];

int main()

{

    int n, m;

    cin >> n >> m;

    for(int i = 1;i <= n; ++i)

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

    cin >> b[i];

   for(int i = 1;i <= n; ++i)

      for(int j = 1; j <= n; ++j)

      {

              if(a[i] == b[j])

                      dp[i][j] = dp[i - 1][j - 1] + 1;

               else dp[i][j] = max(dp[i - 1][j],dp[i ][j - 1]);

        }

   cout << dp[n][m] << '\n';

   return 0;

   

2.求出具体子序列

a13425
b14352

dp12345
11111
211222
312222
412223
512233

132

(i,j)从(n,m)往回走,当a[i]=b[j]时,往左上角走变为(i-1,j-1),此时找到了一个公共元素a[i](或blj]),否则往左边或上边走(选择较大的方向)。

走到新位置后重复以上判断,直到走出边界

#include <bits/stdc+.h>
using namespace std;
using ll = long long;
const ll p= 1e9 + 7;
const int int = 1e9, N = 1e3 + 9;
int a[N], b[N], dp[N][N];
int main()

{
     int n, m;

     cin >> n >>m;

     for(int i = 1; i <= n; ++i)

     cin >> a[i];

      for(int i = 1; i <= m; ++i)

    cin >> b[i];

     for(int i = 1; i <= n; ++i)

     {
          for(int j= 1; j<= m; ++ j)

           {

             if(a[i] == b[j])

              dp[i][j] = dp[i - 1][j - 1] + 1;

              else dp[i][j] = max(dp[i][j-1],dp[i - 1][j]);

              }

    }

   vector<int> v;

   int x = n, y = n;

   while(x && y)

   {

       if(a[x] == b[y])

        {

            v.push_back(a[x]);

             x --, y--;

         }

          else (dp[x - 1][y] > dp[x][y - 1])

        x --;

         else y--;

  }

reverse(v.begin(),v.end());

 for(const auto &i : v)

 cout << i << ' ';

 return 0;

}

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

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

相关文章

【专题】数据库原理与应用之故障恢复

1. 数据库故障恢复概述 数据库的可恢复性&#xff1a; DBMS能把数据库从被破坏、不正确的状态、恢复到最近一个正确的状态。 恢复管理任务的种类&#xff1a; 一是在未发生故障而系统正常运行时&#xff0c;采取一些必要措施为恢复工作打基础。 二是在发生故障后进行恢复处…

EXCEL 或 WPS 列下划线转驼峰

使用场景&#xff1a; 需要将下划线转驼峰&#xff0c;直接在excel或wps中第一行使用公式&#xff0c;然后快速刷整个列格式即可。全列工下划线转为格式&#xff0c;使用效果如下&#xff1a; 操作步骤&#xff1a; 第一步&#xff1a;在需要显示驼峰的一列&#xff0c;复制以…

MODBUS TCP转CANOpen网关

Modbus TCP转CANopen网关 型号&#xff1a;SG-TCP-COE-210 产品用途 本网关可以实现将CANOpen接口设备连接到MODBUS TCP网络中&#xff1b;并且用户不需要了解具体的CANOpen和Modbus TCP 协议即可实现将CANOpen设备挂载到MODBUS TCP接口的 PLC上&#xff0c;并和CANOpen设备…

分布式----Ceph部署

目录 一、存储基础 1.1 单机存储设备 1.2 单机存储的问题 1.3 商业存储解决方案 1.4 分布式存储&#xff08;软件定义的存储 SDS&#xff09; 1.5 分布式存储的类型 二、Ceph 简介 三、Ceph 优势 四、Ceph 架构 五、Ceph 核心组件 #Pool中数据保存方式支持两种类型&…

自动驾驶系列—面向自动驾驶的模型迭代:工具、平台与最佳实践

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

Spring Boot3自定义starter

1、加入必要依赖 plugins {id javaid org.springframework.boot version 3.2.6id io.spring.dependency-management version 1.1.5 } group org.example.test.starter version 1.1.0jar{enabledtrue// resolveMainClassName }java {toolchain {languageVersion JavaLanguage…

AI开发-计算机视觉库-OpenCV

1 需求 官网&#xff1a;OpenCV - Open Computer Vision Library 2 接口 3 示例 import cv2image cv2.imread("./data/train/1_1.jpg") print(type(image)) 4 参考资料

delphi fmx android 离线人脸识别

搜遍全网都没有找到delphi android 能用的 离线人脸识别,无需注册什么开发者 有这方面需求的可以用fsdk 这边用的luxand.FSDK8.0 android下的注册号要自己找下 1,用老猫的工具将android 下的sdk,FSDK.java 编译成FSDK.jar 老猫的工具 2,用上面的工具将FSDK.jar 生成de…

RabbitMQ教程:工作队列(Work Queues)(二)

RabbitMQ教程&#xff1a;工作队列&#xff08;Work Queues&#xff09;&#xff08;二&#xff09; 一、引言 在快节奏的软件开发世界中&#xff0c;我们经常面临需要异步处理任务的场景&#xff0c;比如在Web应用中处理耗时的图片处理或数据分析任务。这些任务如果直接在用…

乐维网管平台(七):网络稳定与高效的“安全锦囊”

试想一下&#xff0c;你给电脑升级了一个软件&#xff0c;升级完成后发现有BUG&#xff0c;经常无故卡死&#xff0c;这时候想回退或重新安装旧版本…相对地&#xff0c;一家企业的网络管理员&#xff0c;在对公司的核心交换机进行复杂的配置调整时&#xff0c;一个小小的疏忽&…

时代变迁对传统机器人等方向课程的巨大撕裂

2020年之后&#xff0c;全面转型新质课程规划&#xff0c;传统课程规划全部转为经验。 农耕-代表性生产关系-封建分配制度主要生产力-人力工业-代表性生产关系-资本分配制度工业分为机械时代&#xff0c;电气时代&#xff0c;信息时代&#xff1b;主要生产力-人力转为人脑&…

Spring6 AOP 面向切面编程

1. 概念 面向切面编程&#xff1a;一种编程思想。proxy动态代理&#xff08;实现了这种思想&#xff09;&#xff1a;在原方法执行时&#xff0c;给原方法的前面或着后面增加其他的方法。增加的方法并不会写在原方法中 原方法就是目标方法&#xff0c;增加的方法就是代理方法 …

计算机组成与原理(2) basic of computer architecture

Instruction Set Architecture (ISA) 和 Hardware System Architecture (HSA) 是计算机体系结构中两个重要的层次&#xff0c;它们各自的职责和作用如下&#xff1a; Instruction Set Architecture (ISA) 定义 ISA是指令集体系结构&#xff0c;是硬件和软件之间的接口。它定义…

window的wsl(Ubuntu)安装kafka步骤

环境&#xff1a;Win11 WSL(Linux子系统Ubuntu) apache-zookeeper-3.9.3-bin kafka_2.12-3.8.1 思路&#xff1a;apache上分别下载zookeeper和kafka&#xff0c;在wsl环境安装。在kafka上创建消息的topic&#xff0c;发送消息&#xff0c;接受消息&#xff0c;验证是否安…

数据结构树和二叉树知识点和递归序列

二叉树知识点 一.树的概念1.1关于树的名词解释 二.二叉树的概念1. 二叉树性质&#xff1a; 三.满二叉树与完全二叉树递归前序遍历递归中序遍历递归后续遍历 一.树的概念 树是一种非线性数据结构&#xff0c;它是由n个或大于n个的结点来组成具有层次关系的一个集合&#xff08;…

速通前端篇 —— CSS

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;速通前端 目录 CSS的介绍 基本语法规范 CSS选择器 标签选择器 class选择器 id选择器 复合选择器 通配符选择器 CSS常见样式 颜…

使用 Elastic 3 步实现基于 OTel 的原生 K8s 和应用可观测性

作者&#xff1a;来自 Elastic Bahubali Shetti Elastic 的 OpenTelemetry 发行版现已支持 OTel Operator&#xff0c;可使用 EDOT SDK 自动检测应用程序&#xff0c;并管理 EDOT OTel Collector 的部署和生命周期以实现 Kubernetes 可观察性。了解如何通过 3 个简单步骤进行配…

stack、queue、priority_queue、deque的使用和模拟实现

目录 1.容器适配器 2.stack stack的常用接口及使用示例 stack的模拟实现 3.queue queue的常用接口及使用示例 queue的模拟实现 4.priority_queue priority_queue的常用接口及使用示例 priority_queue的模拟实现 5.deque 认识deque deque底层的数据结构 deque和ve…

Linux的cuDNN(cudnn)安装教程(CUDA(cuda\cuda toolkit))

CUDA(cuda\cuda toolkit&#xff09;安装教程 https://blog.csdn.net/huiyayaya/article/details/143863835?spm1001.2014.3001.5502官网下载cudnn https://developer.nvidia.com/rdp/cudnn-archive这个下载到自己的电脑 下载到本地就好 复制到服务器 切换到cudnn文件所在目…

Kafka中ACKS LSO LEO LW HW AR ISR OSR解析

名称解释 ACKS&#xff08;Acknowledgments&#xff09;确认、回执 LW&#xff08;Low watermark&#xff09;低水位、LSO&#xff08;Log start offset&#xff09;起始偏移量 HW&#xff08;High watermark&#xff09;高水位 LEO&#xff08;Log end offset&#xff09;…