【算法】动态规划之线性DP问题

news2025/1/18 9:54:09

 前言:

本系列是看的B站董晓老师所讲的知识点做的笔记

董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com)

树塔-记忆化搜索

特点(前提):从上向下的累加和是不能重复使用的,从下向上的累加和是可以重复使用的

把题目变成二叉树的形式:4的左子树分别是下一行的8和下一行右边的3,依次类推,每一个树的左子树都是他的下一行的数和下一行数的右边的那个数

int a[9][9] =
{   {1},
	{4,6},
	{8,3,9},
	{5,7,2,1}};
     int n = 4;
    int f[9][9];//记录从上向下的累加和
	int dfs(int x, int y)
	{
		if (f[x][y] != 0) return f[x][y];//说明该点已经遍历过
		if (x == n - 1) f[x][y] = a[x][y];//说明已经全部遍历完了
		else
		f[x][y] = a[x][y] + max(dfs(x + 1, y), dfs(x + 1, y + 1));
		return f[x][y];
	}

线性DP

数塔

int calu(int x, int y)
{
	int x,  y;
	for (x = n - 2; x >= 0; x--)
		for (y = 0; y <= x; y++)//这样就可以弄成塔的形式
			a[x][y] += max(a[x + 1][y], a[x + 1][y + 1]);
	cout << "max=" << a[x][y];
}

如果需要输出路径的话,需要有一个前驱路径数组p[x][y]和一个备份数组b[x][y];

前驱路径数组主要是记录y的增值的,把两种情况(a[x + 1][y]>/<=a[x + 1][y + 1])分别设为0和1,r然后在通过遍历数组b[x][y],y=y+p[x][y]进行输出

最长上升子序列

B3637 最长上升子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

动态规划(O(n²))


    for (int i = 1; i <= n; i++) f[i] = 1;//把初始化化长度都设为1
    for (int i = 2; i <= n; i++)
   {
    for (int j = 1; j < i; j++)
    if (a[i] > a[j]) f[i] = max(f[j] + 1,f[i]);//分别依次计算不同下标时候的长度
    for (int i = 1; i <= n; i++) ans = max(ans, f[i]);//遍历寻找长度最长的长度
   }

二分查找

思想:

新进来一个元素a[i]:
(1)大则添加:如果a[i]大于b[len],直接让b[++len]=a[i]。即b数组的长度增加1,而且添加了一个元素。

(2)小则替换:如果a[i]小于或等于b[len],就用a[i]替换掉b数组中第一个大于或等于a[i]的元素。
    假设第一个大于a[i]的元素是b[j],那么用a[i]换掉b[j]后,会使得b[1...j]这个上升子序列的结尾元素更小。对于一个上升子序列,其结尾元素越小,越有利于续接其它元素,也就越可能变得更长。

注意:

b数组不是存储的最长上升子序列,但是子序列的长度相同

 核心代码

二分查找第一个大于等于x的位置

int find(int x) {
    int l = 1, r = len, mid;
    while (l <= r) {
        int mid = l + r >> 1;
        if (x > b[mid]) l = mid + 1;
        else r = mid - 1;
    }
    return l;
}

新增元素代码

for (int i = 0; i < n; i++) {
        if (b[len] < a[i]) b[++len] = a[i];
        else b[find(a[i])] = a[i];
    }

全部代码

#include<iostream>
using namespace std;
const int N = 10010;
int n, a[N], b[N], len;
int find(int x) {
    int l = 1, r = len, mid;
    while (l <= r) {
        int mid = l + r >> 1;
        if (x > b[mid]) l = mid + 1;
        else r = mid - 1;
    }
    return l;
}
int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    b[0] = -2e9;
    for (int i = 0; i < n; i++) {
        if (b[len] < a[i]) b[++len] = a[i];
        else b[find(a[i])] = a[i];
    }
    printf("%d\n", len);
    return 0;
}

最长公共子序列 

1.最长公共子序列不是连续的一段区间

2.记录路径的时候前驱数组可以去掉

1.思路

2.核心代码

 for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
    if (a[i] == b[j]) f[i][j] = f[i - 1][j - 1] + 1;
    else f[i][j] = max(f[i - 1][j - 1], max(f[i - 1][j], f[i][j - 1]));

3.题目一

P1439 【模板】最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 

 

前提:

两个排列都是1到n的排列,说明元素都是相同的只是顺序不同,

思路:

把LCS转换成LIS 

原因:

通过离散化可以得到一个性质。

离散化步骤:

A:3 2 1 4 5
B:1 2 3 4 5
重新把A,B数组中的元素替换掉,使得A数组是其次递增的

标个号:把3标成a,把2标成b,把1标成c.…于是变成:
A: a b c d e

B: c b a d e
结论:最长公共子串的长度不会改变,又因为A数组是递增的,所以说在B数组中递增的子序列就是A的子序列

离散化代码:
for (int i = 1; i <= n; i++)
    {
        cin >> m;
        line[m] = i;
    }

最长公共子串

核心代码

for(int i=1; i<=strlen(a); i++){
    for(int j=1; j<=strlen(b); j++){
      if(a[i-1]==b[j-1]) f[i][j]=f[i-1][j-1]+1;
      else f[i][j]=0;
      if(f[i][j]>max)
      max=f[i][j];
    }

编辑距离

题目

P2758 编辑距离 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

二维思路

一维思路

具体分析

1.初始化,看上面的矩阵,第一行的意思是“LOVER"此时是空串,则“NOTV”那里有几个字符就需要删除几个字符

 for(int i=1;i<=la;i++) f[i][0]=i;
 for(int i=1;i<=lb;i++) f[0][i]=i;

2. 一维思路如果不清楚的话,就对照着图片上方的四个格子推一次

总结:

1.LIS:Longest Increasing Subsequence    最长递增子序列

LCS:Longest Common Subsequence  最长公共子序列

2.公共子串:字符必须是连续相等的;

公共子序列:字符必须是相等的,可以不连续。

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

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

相关文章

Golang — map的使用心得和底层原理

map作为一种基础的数据结构&#xff0c;在算法和项目中有着非常广泛的应用&#xff0c;以下是自己总结的map使用心得、实现原理、扩容机制和增删改查过程。 1.使用心得&#xff1a; 1.1 当map为nil和map为空时&#xff0c;增删改查操作时会出现的不同情况 我们可以发现&#…

浅谈如何做好软件项目

如何做好软件项目&#xff0c;这是摆在软件实施团队每个人面前的关键问题。笔者在此提出一些浅见&#xff0c;供大家参考。欢迎在评论区交流&#xff01; 目录 【摘要】 【正文】 一、树立正确的需求调研理念 二、谋定而后动的开发工作 三、大道至简的系统设计 四、专注项…

Yoast SEO Premium插件下载,提升您的网站SEO排名

在当今数字化时代&#xff0c;网站的搜索引擎优化&#xff08;SEO&#xff09;至关重要。它不仅影响着网站的可见度&#xff0c;更直接关系到您的在线业务成功与否。如果您正在寻找一个能够显著提升网站SEO表现的工具&#xff0c;Yoast SEO Premium插件将是您的理想选择。 为什…

OpenHarmony 实战开发——如何编译OpenHarmony自带APP

概述 OpenHarmony 的主干代码是开源社区的重要学习资源&#xff0c;对于想进行应用开发和熟悉 OpenHarmony 能力的同学主干代码是非常重要的资源&#xff0c;在主干代码的 applications 目录里聚集了很多原生的应用实现&#xff0c;那么如何编译这些代码就是我们这篇文章的主要…

springboot+vue+mybatis灵活就业服务平台+PPT+论文+讲解+售后

随着网络科技的不断发展以及人们经济水平的逐步提高&#xff0c;网络技术如今已成为人们生活中不可缺少的一部分&#xff0c;而微信小程序是通过计算机技术&#xff0c;针对用户需求开发与设计&#xff0c;该技术尤其在各行业领域发挥了巨大的作用&#xff0c;有效地促进了灵活…

draw.text((left, top - 15), text,font=font, fill=“green”)

这是一个Python PIL库中的方法&#xff0c;用于在图片上绘制文本。具体来说&#xff0c;它可以在指定的位置绘制指定的文本&#xff0c;并使用指定的字体、颜色等参数进行渲染。其中&#xff0c;left和top是文本绘制的左上角坐标&#xff0c;text是要绘制的文本内容&#xff0c…

【linux学习】多线程(1)

文章目录 线程的概念线程与进程 线程的用法线程的创建多线程 线程的等待线程锁死锁 线程的概念 在Linux中&#xff0c;线程&#xff08;Thread&#xff09;是程序执行流的最小单位&#xff0c;是进程中的一个实体&#xff0c;负责在程序中执行代码。线程本身不拥有系统资源&…

只需三步将Kimi接入微信公众号

今天我将手把手交大家如何把Kimi大模型接入微信公众号&#xff0c;创建属于你自己的公众号智能助理&#xff0c;让你的公众号具备智能对话、文件阅读、信息搜索等强大功能&#xff0c;同时提高用户互动率、减少人工客服压力等。 废话不多说&#xff0c;先来看看实际效果吧~ 一…

简约在线生成短网址系统源码 短链防红域名系统 带后台

简约在线生成短网址系统源码 短链防红域名系统 带后台 安装教程&#xff1a;访问 http://你的域名/install 进行安装 源码免费下载地址抄笔记 (chaobiji.cn)https://chaobiji.cn/

AI视频教程下载:用ChatGPT自动化各种工作任务

这是一门实用的无代码课程&#xff0c;旨在通过使用ChatGPT高级数据分析和代码解释器提高生产力。 通过让ChatGPT代码解释器创建程序来自动化单调的任务&#xff0c;提高您的计算机生产力。 这门课程专为那些渴望快速使用小型实用程序的人设计&#xff0c;不需要编程知识。相…

下水道井盖多分类检测定位

下水道井盖识别&#xff0c;多分类&#xff0c;使用yolov5训练&#xff0c;采用一部分开源数据集和自建数据集。python pytorch opencv 深度学习#人工智能#深度学习#目标检测

在另外一个页面,让另外一个页面弹框显示操作(调佣公共的弹框)

大概意思是&#xff0c;登录弹框在另外一个页面中&#xff0c;而当前页面不存在&#xff0c;在当前页面中判断如果token不存在&#xff0c;就弹框出登录的弹框 最后一行 window.location.href … 如果当前用户已登录&#xff0c;则执行后续操作(注意此处&#xff0c;可不要)

7.STL_string1.0(详细)

目录 1. 什么是STL 2. STL的版本 3. STL的六大组件 1. 为什么学习string类&#xff1f; 1.1 C语言中的字符串 2. 标准库中的string类 2.1 string类(了解) 2.2 string类的常用接口说明 1. string类对象的常见构造 2. string类对象的容量操作 reserve 3. string类对象…

省级生活垃圾无害化处理率面板数据(2004-2022年)

01、数据简介 生活垃圾无害化处理率是指经过处理的生活垃圾中&#xff0c;达到无害化标准的垃圾所占的比例。这一指标是衡量城市垃圾处理水平的重要标准&#xff0c;反映了城市对垃圾进行有效管理和处理的能力。 生活垃圾无害化处理的主要方式包括生活垃圾焚烧、生活垃圾卫生…

数据挖掘原理与应用------分类预测

在数据挖掘和机器学习领域&#xff0c;TPR&#xff08;True Positive Rate&#xff09;是指在实际为阳性的情况下&#xff0c;模型正确预测为阳性的比例。TPR也被称为灵敏度&#xff08;Sensitivity&#xff09;或召回率&#xff08;Recall&#xff09;。它是评估分类模型性能的…

构建教育新未来:智慧校园平台的深度解读与全景呈现

引言 在全球数字化转型的大潮中&#xff0c;智慧校园平台作为教育信息化的重要载体&#xff0c;正以前所未有的姿态颠覆传统的教育模式&#xff0c;引领教育行业步入一个崭新的时代。这个融合了大数据、人工智能、云计算、物联网等一系列前沿科技的平台&#xff0c;以其强大的功…

QT day2 作业

头文件 #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include <QDebug> #include<QIcon> #include<QLabel> #include<QMovie> #include<QLineEdit> #include<QPushButton> QT_BEGIN_NAMESPACE namespace Ui { class …

浅谈SiC MOSFET之MOSFET

1.掺杂后的半导体 P型半导体&#xff0c;多子是空穴&#xff0c;少子是自由电子。 N型半导体&#xff0c;多子是自由电子&#xff0c;少子是空穴。 2.电中性 尽管他们分别有着空穴带正电&#xff0c;自由电子带负电&#xff0c;但是整体上是电中性的。 以P型半导体为例&…

Leaflet.canvaslabel在Ajax异步请求时bindPopup无效的解决办法

目录 前言 一、场景重现 1、遇到问题的代码 2、问题排查 二、通过实验验证猜想 1、排查LayerGroup和FeatureGroup 2、排查Leaflet.canvaslabel.js 三、柳暗花明又一村 1、点聚类的办法 2、歪打正着 总结 前言 在上一篇博客中介绍了基于SpringBoot的全国风景区WebGIS按…

实验室纳新宣讲会(java后端)

前言 2024-5-12 22:00:39 这是陈旧已久的草稿 2021-09-16 15:41:38 发布一下 当时我进入实验室&#xff0c;也是大二了&#xff0c;实验室纳新需要宣讲&#xff0c; 但是当时有疫情&#xff0c;又没宣讲成。 实验室纳新宣讲会&#xff08;java后端&#xff09; 首先&#x…