算法--动态规划(线性DP、区间DP)

news2025/1/25 9:11:48

这里写目录标题

  • tip
    • 数组下标从0开始还是从1开始
  • 数学三角形
    • 介绍
    • 算法思想
    • 例题+代码
  • 最长上升子序列
    • 介绍
    • 算法思想
    • 例题+代码
  • 最长公共子序列
    • 介绍
    • 算法思想
    • 例题+代码

tip

数组下标从0开始还是从1开始

在这里插入图片描述
如果代码中涉及到数组下标为i-1(有时候哪怕不是同一个数组也符合情况,因为是针对同一组数据进行的多个数组设置),那么我们可以使 i 从 1开始,这样,当 i = 1 时,就取到了[0],如果这个位置有特殊情况,那么这样一来我们也不必使用 if ,直接对 f [0]设置一个特殊值即可

注意,“输入”与“使用”是统一的,即如果输入数组时决定了使用 i 从 1 开始,那么到时候使用或者取元素时,一定要记得是从 1 开始,
如果输入决定了是从0开始,那么到时候取元素的时候,记得从0开始

数学三角形

介绍

在这里插入图片描述
从顶部出发,可以向左下或者右下移动,最后形成一条路径,找到一条路径使得路径上的数字之和最大

算法思想

在这里插入图片描述
首先我们对三角形的各个数进行编码,从上到下每行从1开始表上行号,之后,东北方向偏45度进行列号的编排,最左边是1列,之后往右依次是2,3,…,这样一来,我们就可以标定某个元素的位置,这也符合三角形位置的数据在数组内存储时的位置

对于动态规划,仍然是状态表示和状态计算,
状态表示:因为每个元素由一个二维数对进行位置表示,所以,状态表示仍然是一个二维的,如上图所示,属性是max
状态计算:由前面的经验可以总结出:状态计算是一个情况的划分,划分的是上一层的情况,即仅研究上一层即可,之后递推原理会帮助代码完成
上一层的状态有两个,一个来自左上,一个来自右上。
两种划分都是曲线救国的思路,即 f [ i - 1 , j - 1 ] + a[ i , j ],另一个是 f [ i - 1 , j ] + a[ i , j ]
其中 a数组存储了所有的数据,a [ i , j ]就是表示[ i , j ]位置的值

例题+代码

在这里插入图片描述
在这里插入图片描述
首先,a[N][N]数组是用来存储所有的数据的
f[N][N]是状态表示

之后,main函数里
首先读入n
之后由于这组数据会涉及到 i-1 ,所以使用数组存数据时,i从1开始到小于等于n,j从1开始到小于等于 i (因为是三角形),读入到a[][]数组中,给[0][x] [x][0]这些位置空出来,方便一些特殊情况时拿来使用(包括a数组自己使用或者其他数组使用,总之这个位置要留出来)
之后初始化状态表示,因为状态表示数组涉及到某一点的上边两个角,所以,要处理好边界问题,我们的 i 从 0开始到等于n,j 从 0开始到等于 i + 1 (这样做可以在原来的数据基础上,多加一个0行和0列被初始化,这样的话,当我们遇到如下图所示情况时,就不会出错了),且f[i][j] = - INF,将所有的位置初始化为负无穷,这样的话,最终原数据的外面的位置下标,f[][]的值是负无穷,这样做是为了当我们有路径来到了原数据的外面,那最后的值一定是负无穷,这样我们就可以筛选出来哪些路径是经过了原数据的外面的位置得到的,这些数据可以排除
之后初始化f[1][1] = a[1][1],因为第一个还没有经过任何其他的点,可以初始化为1
之后for循环,i 从 2 开始到等于n(之所以从2开始,是因为1就一个节点,已经被初始化了)
二层循环 ,j 从 1 开始到等于i (仍然是因为输入时是三角形输入)
f[ i ][ j ] = max(f[ i - 1 ][j - 1] + a[ i ][ j ] , f[ i - 1 ][ j ] + a[ i ][ j ])
到此为止,我们就已经可以拿到所有 i j 点的状态了,我们由于是想求最大路径,所以对叶子结点的状态进行求max即可,这里由于之前所有的f都被初始化为了负无穷,所以这样答案也初始化为负无穷去进行比较,而就算有路径经过了负无穷,那最后的值是-INF+一些正数,肯定比-INF要大一点点,所以,res用-INF存储,最后参与到max中
在这里插入图片描述

最长上升子序列

介绍

在这里插入图片描述
在这里插入图片描述
例如这样一个序列,最长子序列就是 1 2 5 6,长度最长是4

算法思想

在这里插入图片描述
状态表示可以使用一维的,即所有以“第” i 个数结尾的上升子序列,属性是max
状态计算:
划分依据:上一层是第几个数
如果上一层没有数,那么说明只有“第i个数”这一个数
如果上一层的数是第 j 个数,那么可以递推为 f [ j ] + 1(这个j是有条件的,要满足aj < ai)
最后对所有的f[ j ] + 1 (j从0开始到 i - 1)取max就是答案
在这里插入图片描述

例题+代码

在这里插入图片描述
在这里插入图片描述
a数组表示将数据进行存储,f数组表示状态表示
在mian函数中
首先输入n
i 从 1 到等于n ,输入a[ i ]
之后对for从1到等于n
f[ i ] = 1 ,(所有的 f 最少是1,所以先初始化为1)
之后,对于for循环,j 从 1 开始到小于 i (因为状态计算时,是以" "前一个数"是第几个数 " 进行划分的,所以j从1到小于i,表示遍历所有划分的情况,为后续取max做准备,这样就可以找到最大的子序列对应的是哪个 j ,因为每个j对应的f[j] 是不同的)
同时判断 if (a[j] < a[i])才是合法的(因为是上升子序列,要求单调)
之后 f[i] = max(f[i] , f[j]+1)(对所有的划分进行max)
在这里插入图片描述

最后,把所有的 f[i] 进行取max,即,将所有的情况取最大值,就是最大子序列

补充:
在这里插入图片描述
在“动态规划(2)”中00:54时,介绍了如何将最长子序列保存下来

最长公共子序列

介绍

在这里插入图片描述

算法思想

在这里插入图片描述
首先,对于状态表示,集合方面,表示所有在第一个序列的前i个字母中出现,且在第二个序列的前 j 个字母中出现的公共子序列,属性是max

之后对于状态计算
可以对公共子序列是否包含a[i] b[j]进行划分,0表示不包含,1表示包含,如上图
之后对于00:
f [ i - 1 , j - 1]
对于11:
f [ i - 1 , j - 1]
对于上面这两个,毫无疑问,确实是这样表示的,
但是对于01和10,我们下面这种表示,是错误的,拿01举例来说,我们想要的是不包含ai但是必须要有bj,而f [i - 1 , j ]表示不包含ai,但是可以有bj也可以没有,所以他是错的,但是f [i - 1 , j ]包含了01这种情况,由于我们是求最大值,而且f的属性也是max,所以,既然f [i - 1 , j ]包含了01的情况,那么就可以拿来进行对比,因为如果对于f [i - 1 , j ]来说,如果01是其所有情况的最大值,那么就符合我们的要求,如果不是,那么我们也没必要再关注01了,而是其他某种情况,所以可以直接用f [i - 1 , j ]。10同理
对于01:
f [i - 1 , j ]
对于10:
f [ i , j - 1 ]

最后补充:
在这里插入图片描述
我们在写代码时,不用写00的情况,因为这种情况也被包含在了f [i - 1 , j ]和f [i , j - 1]两种情况里,所以我们在写代码时只需要考虑后面三种情况即可

例题+代码

在这里插入图片描述
在这里插入图片描述
n和m表示a和b字符串的长度
char a b数组用来存储字符串
f数组是状态表示

之后在main里:
首先输入n 和 m
之后输入字符串,使用%s,以及数组名(这里是数组名+1,可以从数组的第二个位置,也就是下标为1的位置开始将整个字符串都读入,因为代码中出现了i-1)
之后for i 从1~=n
二重循环 j 从1~=m(也就是将所有的 f 进行了遍历)
f[i][j] = max (f[i-1][j] , f[i][j-1]),先将这两个进行取max
之后对11这种情况进行判断
只有当a[i] == b[j]时,才会有第三种情况,所以只有该条件成立,将第三种情况放入max中
最后输出 f[n][m]

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

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

相关文章

sql-labs第46关 order by盲注

sql-labs第46关 order by盲注 来到了第46关进入关卡发现让我们输入的参数为sort&#xff0c;我们输入?sort1尝试&#xff1a; 输入?sort2,3,发现表格按照顺序进行排列输出&#xff0c;明显是使用了order by相关的函数。 我们将参数变成1进行尝试&#xff0c;就会报错&…

uni-app原生api的promise化以解决异步等待问题分析

相信各位在进行uni-app开发的时候会遇到各种关于异步回调问题&#xff0c;例如要传code给后端以换取session_key&#xff0c;在这之前需要先调用 uni.login&#xff0c;所以执行的顺序是必须同步等待的。在写这篇文章之前对于整体的流程概念需要做一个梳理&#xff0c;以便能更…

Laravel03 路由到控制器与连接数据库

Laravel03 路由到控制器与连接数据库 1. 路由到控制器2. 连接数据库 1. 路由到控制器 如下图一些简单的逻辑处理可以放在web.php中&#xff0c;也就是路由的闭包函数里面。但是大的项目&#xff0c;我们肯定不能这么写。 为什么保证业务清晰好管理&#xff0c;都应该吧业务逻辑…

ubuntu20.04安装和使用 Maldet (Linux Malware Detect)

1、下载 Maldet sudo wget http://www.rfxn.com/downloads/maldetect-current.tar.gz 2、解压Maldet sudo tar -xvf maldetect-current.tar.gz 3、进入到Maldet目录&#xff0c;然后运行安装脚本 sudo ./install.sh 4、安装ClamAV sudo apt-get update sudo apt-get in…

卡诺图之间的运算(拓展应用)

文章目录 1.卡诺图运算的基本规律⑴卡诺图之间的或运算⑵卡诺图之间的与运算⑶卡诺图之间的异或和同或运算 2.利用卡诺图进行运算&#xff08;并化简&#xff09;3.特殊卡诺图与卡诺图模块化⑴异或逻辑函数的卡诺图⑵同或逻辑函数的卡诺图⑶卡诺图的模块化 4.可能的题型&#x…

使用 JMeter 生成测试数据对 MySQL 进行压力测试

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

3分钟看懂设计模式02:观察者模式

一、什么是观察者模式 观察者模式又叫做发布-订阅模式或者源-监视器模式。 结合它的各种别名大概就可以明白这种模式是做什么的。 其实就是观察与被观察&#xff0c;一个对象&#xff08;被观察者&#xff09;的状态改变会被通知到观察者&#xff0c;并根据通知产生各自的不…

二 线性代数-向量

1、向量的表示方法&#xff1a; 其中的 i、j、k是坐标轴方向的单位向量。 2、向量的模&#xff1a; 用坐标计算的方法&#xff1a; 3、向量的运算&#xff1a; 3.1 向量的加法减法&#xff1a; 3.2 向量的数乘&#xff1a; 拉格朗日乘数法的 基础 公式。 3.3 向量的数量积&a…

conda 导出/导出配置好的虚拟环境

一. 导出环境配置&#xff08;yml文件&#xff09; 1. 在主目录下激活虚拟环境&#xff08;UE4是我的虚拟环境名称&#xff0c;请根据你自己的名称进行修改&#xff09; conda activate UE4 2. 运行此代码 conda env export > environment.yml 二. 导入环境配置&#xf…

oracle官网下载早期jdk版本

Java Downloads | Oracle JDK Builds from Oracle 以上压缩版&#xff0c;以下安装版 Java Downloads | Oracle 该链接往下拉能看到jdk8和jdk11的安装版 -- end

每日一题 — 移动零

力扣链接&#xff1a;283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;利用双指针将数组分为三个区间&#xff0c;三个区间分别表示的是&#xff1a;非0元素、0、待处理元素 当arr[cur] ! 0时 [0,dest]区间就需要加一&#xff0c;所以dest 然后再交换a…

Java SpringBoot 获取 yml properties 自定义配置信息

Java SpringBoot 获取 yml properties 自定义配置信息 application.yml server:port: 9090servlet:context-path: /app第一种方法 HelloController package com.zhong.demo01.controller;import org.springframework.beans.factory.annotation.Value; import org.springfram…

Python字符串切片操作原来这么简单!

字符串切片是Python中用于从字符串中提取子串的强大工具。通过指定开始和结束下标&#xff0c;以及可选的步长参数&#xff0c;可以轻松地截取字符串的一部分。 1.字符串切片原理 从字符串中复制指定的一段代码&#xff0c;生成一个新的字符串 2.字符串切片语法 字符串[开始…

2018-02-14 新闻内容爬虫【上学时做论文自己爬新闻数据,原谅我自己懒发的图片】

2018-02-14新闻内容爬虫【上学时做论文自己爬新闻数据&#xff0c;原谅我自己懒发的图片】资源-CSDN文库https://download.csdn.net/download/liuzhuchen/88878591爬虫过的站点&#xff1a; 1QQ新闻 1&#xff0c;准备爬取滚动新闻页面 2 通过F12 开发工具查找发现&#xff…

Linux配置JDk环境

下载jdk 官网地址&#xff1a;Java Downloads | Oracle 将下载的jdk上传到服务器 不管你使用什么工具和方法&#xff0c;只要将安装包上传到服务器就可以了 解压文件 tar -xvf jdk-8u341-linux-x64.tar.gz 配置环境变量 用vim /etc/profile进入编辑状态&#xff0c;加入下边…

python中的数字类型Number

Python 数字(Number) Python 数字数据类型用于存储数值。 数据类型是不允许改变的&#xff0c;这就意味着如果改变数字数据类型的值&#xff0c;将重新分配内存空间。 以下实例在变量赋值时 Number 对象将被创建&#xff1a; var1 1 var2 10Python 支持三种不同的数值类型…

2024年阿里云服务器新购、续费、升级优惠政策汇集!

2024年阿里云服务器购买、续费、升级优惠政策整理&#xff0c;阿里云服务器优惠价格表&#xff1a;轻量2核2G3M服务器61元一年、2核4G4M带宽165元1年&#xff0c;云服务器4核16G10M带宽26元1个月、149元半年&#xff0c;阿里云ECS云服务器2核2G3M新老用户均可99元一年续费不涨价…

【开源】使用opencv进行交互式抠图,让你开发效率翻倍

这是一个简单的交互式图像分割应用程序&#xff0c;由python opencv和pyqt编写。 这个应用程序在opencv中应用Grabcut算法对图像进行抠图。Grabcut是Graphcut算法的改进版本。查看这些论文(paper1, paper2)了解详细信息~~ gui部分主要来自这个伟大的工作labelImg。这是一个非常…

【报错处理】命令提示符安装npm install yarn -g失败两种解决方法

目录 方法1&#xff1a;方法2&#xff1a; 方法1&#xff1a; 等待两分钟后发现总是显示如下报错&#xff1a; 在搜索栏搜索命令提示符&#xff0c;将命令提示符以管理员身份运行&#xff0c;如果弹出窗口选择“是”。 3.接着输入命令&#xff0c;结果还是报错&#xff0c;方…

【手机端测试】adb基础命令

一、什么是adb adb&#xff08;Android Debug Bridge&#xff09;是android sdk的一个工具 adb是用来连接安卓手机和PC端的桥梁&#xff0c;要有adb作为二者之间的维系&#xff0c;才能让用户在电脑上对手机进行全面的操作。 Android的初衷是用adb这样的一个工具来协助开发人…