当前位置: 首页 > news >正文

C++ 动态规划

子序列子串相关

单个指一个数组或字符串,两个指两个数组或字符串。

最长上升子序列-单个

dp[i]:以下标i为结尾的递增的最长子序列长度

位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int sz=nums.size();// dp[i] i结尾的最长子序列长度// dp[i]=max(dp[i],dp[j]+1)vector<int> dp(sz,1);int res=1;for(int i=1;i<sz;i++){for(int j=0;j<i;j++){if(nums[i]>nums[j])dp[i]=max(dp[j]+1,dp[i]);}res=max(res,dp[i]);}return res;}
};

最长上升子序列的个数-单个 

最长连续上升子序列-单个

dp[i]:以下标i为结尾的连续递增的子序列长度。

因为本题要求连续递增子序列,所以就只要比较nums[i]与nums[i - 1],而不用去比较nums[j]与nums[i] (j是在0到i之间遍历)。

class Solution {
public:int findLengthOfLCIS(vector<int>& nums) {int sz=nums.size();vector<int> dp(sz,1);int res=1;for(int i=1;i<sz;i++){if(nums[i]>nums[i-1])dp[i]=dp[i-1]+1;res=max(dp[i],res);}return res;}
};

最长重复连续子序列-两个

dp[i][j] :以下标i - 1为结尾的A和以下标j - 1为结尾的B,最长重复子数组长度。

class Solution {
public:int findLength(vector<int>& nums1, vector<int>& nums2) {int sz1=nums1.size(),sz2=nums2.size();vector<vector<int>> dp(sz1+1,vector<int>(sz2+1));int res=0;for(int i=1;i<=sz1;i++){for(int j=1;j<=sz2;j++){if(nums1[i-1]==nums2[j-1])dp[i][j]=dp[i-1][j-1]+1;res=max(res,dp[i][j]);}}return res;}
};

最长重复子序列-两个

dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列。

主要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同

如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;

如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。

即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])。

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int sz1=text1.size(),sz2=text2.size();int res=0;vector<vector<int>> dp(sz1+1,vector<int>(sz2+1));for(int i=1;i<=sz1;i++){for(int j=1;j<=sz2;j++){if(text1[i-1]==text2[j-1])dp[i][j]=dp[i-1][j-1]+1;elsedp[i][j]=max(dp[i-1][j],dp[i][j-1]);res=max(res,dp[i][j]);}}return res;}
};

不相交的线🧵-两个

直线不能相交,这就是说明在字符串A中 找到一个与字符串B相同的子序列,且这个子序列不能改变相对顺序,只要相对顺序不改变,链接相同数字的直线就不会相交。那么就和最长重复子序列一样了!

最大连续子序列的和-单个

具有最大和的连续子数组。

dp[i]:包括下标i(以nums[i]为结尾)的最大连续子序列和.

dp[i]只有两个方向可以推出来:

  • dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和
  • nums[i],即:从头开始计算当前连续子序列和

dp[i] = max(dp[i - 1] + nums[i], nums[i]).

class Solution {
public:int maxSubArray(vector<int>& nums) {int sz=nums.size();vector<int> dp(sz);dp[0]=nums[0];int res=nums[0];for(int i=1;i<sz;i++){dp[i]=max(nums[i],dp[i-1]+nums[i]);res=max(res,dp[i]);}return res;}
};

判断子序列-两个

dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度

  • if (s[i - 1] == t[j - 1])
    • t中找到了一个字符在s中也出现了
  • if (s[i - 1] != t[j - 1])
    • 相当于t要删除元素,继续匹配

if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;,因为找到了一个相同的字符,相同子序列长度自然要在dp[i-1][j-1]的基础上加1(如果不理解,在回看一下dp[i][j]的定义

if (s[i - 1] != t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1]。

class Solution {
public:bool isSubsequence(string s, string t) {int sz1=s.size(),sz2=t.size();vector<vector<int>> dp(sz1+1,vector<int>(sz2+1));for(int i=1;i<=sz1;i++){for(int j=1;j<=sz2;j++){if(s[i-1]==t[j-1]){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=dp[i][j-1];}}}return dp[sz1][sz2]==sz1;}
};

子序列出现的个数-两个?

dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数。

回文子串的个数-单个

计算这个字符串中有多少个回文子串。

判断一个子字符串(字符串下标范围[i,j])是否回文

                                               依赖于

子字符串(下标范围[i + 1, j - 1])) 是否是回文

所以为了明确这种递归关系,dp数组是要定义成一个二维dp数组。

布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果dp[i][j]为true,否则为false。

当s[i]与s[j]不相等,dp[i][j]一定是false。

当s[i]与s[j]相等时,有如下三种情况

  • 情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
  • 情况二:下标i 与 j相差为1,例如aa,也是回文子串
  • 情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。
class Solution {
public:int countSubstrings(string s) {int sz=s.size();int res=0;vector<vector<bool>> dp(sz,vector<bool>(sz));for(int i=0;i<sz;i++)dp[i][i]=true;// 注意遍历顺序for(int i=sz-1;i>=0;i--){for(int j=i;j<sz;j++){if(s[i]==s[j]){if(j-i<=1)  dp[i][j]=true;else dp[i][j]=dp[i+1][j-1];}if(dp[i][j])    res++;}}return res;}
};

最长回文子串-单个

class Solution {
public:string longestPalindrome(string s) {int len = 0;int start = 0;int sz = s.size();vector<vector<bool>> dp(sz, vector<bool>(sz));for (int i = sz - 1; i >= 0; i--) {for (int j = i; j < sz; j++) {if (s[i] == s[j]) {if (j - i < 2)dp[i][j] = true;elsedp[i][j] = dp[i + 1][j - 1];}if (dp[i][j]) {if (j - i + 1 > len) {start = i;len = j - i + 1;}}}}return s.substr(start,len);}
};

最长回文子序列-单个

dp[i][j]:字符串s在[i, j]范围内最长的回文子序列的长度

如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;

如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])。

class Solution {
public:int longestPalindromeSubseq(string s) {int sz=s.size();vector<vector<int>> dp(sz,vector<int>(sz));int res=1;for(int i=0;i<sz;i++)dp[i][i]=1;for(int i=sz-1;i>=0;i--){for(int j=i+1;j<sz;j++){if(s[i]==s[j])  dp[i][j]=dp[i+1][j-1]+2;else    dp[i][j]=max(dp[i+1][j],dp[i][j-1]);res=max(res,dp[i][j]);}}return res;}
};

二维动态

不同路径

不同路径II

01背包🎒

有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

  • 不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。)
  • 放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值

所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])。

如果改为滑动数组,则需倒序遍历背包容量,保证物品只被放进一次。

dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

分割等和子集

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。

目标和

给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。

返回可以使最终数组和为目标数 S 的所有添加符号的方法数。

假设加法的总和为x,那么减法对应的总和就是sum - x。

所以我们要求的是 x - (sum - x) = target

x = (target + sum) / 2

此时问题就转化为,装满容量为x的背包,有几种方法。求组合类问题的公式:

dp[j] += dp[j - nums[i]]

完全背包🎒

零钱兑换II


给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

排列总和 

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的排列的个数。

零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

完全平方数

完全平方数就是物品(可以无限件使用),凑个正整数n就是背包,问凑满这个背包最少有多少物品。

单词拆分

买卖股票

相关文章:

C++ 动态规划

子序列子串相关 单个指一个数组或字符串&#xff0c;两个指两个数组或字符串。 最长上升子序列-单个 dp[i]&#xff1a;以下标i为结尾的递增的最长子序列长度。 位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 1 的最大值。 class Solution { public:int l…...

回溯问题总结

一、子集问题 模板问题 给定一个序列[1,n],求这个序列的所有子集 输入描述&#xff1a; 一个正整数n(1 < n < 12) 输出描述&#xff1a; 每个子集一行&#xff0c;输出所有子集。 输出顺序为&#xff1a; &#xff08;1&#xff09;元素个数少的子集优先输出&#xff1b;…...

GraphRAG如何使用ollama提供的llm model 和Embedding model服务构建本地知识库

使用GraphRAG踩坑无数 在GraphRAG的使用过程中将需要踩的坑都踩了一遍&#xff08;不得不吐槽下&#xff0c;官方代码有很多遗留问题&#xff0c;他们自己也承认工作重心在算法的优化而不是各种模型和框架的兼容性适配性上&#xff09;&#xff0c;经过了大量的查阅各种资料以…...

.net # 检查 带有pdf xss

1.解决pdf含javasprct脚本动作&#xff0c;这里是验证pdf内部事件。相关pdf文件下载&#xff1a; 测试pdf文件 相关包 iTextSharp 5.5.13.4 iTextSharp using iTextSharp.text.pdf; using iTextSharp.text.pdf.parser;private Boolean IsPdfSafe(Stream stream){// PdfReader…...

【React】探讨className的正确使用方式

文章目录 一、className的正确用法二、常见错误解析三、实例解析四、错误分析与解决五、注意事项六、总结 在React开发中&#xff0c;正确使用className属性对组件进行样式设置至关重要。然而&#xff0c;由于JavaScript和JSX的特殊性&#xff0c;开发者常常会犯一些小错误&…...

打靶记录5——靶机hard_socnet2

靶机&#xff1a; https://download.vulnhub.com/boredhackerblog/hard_socnet2.ova目标&#xff1a; 取得root权限 涉及攻击方法 主机发现端口扫描SQL注入文件上传蚁剑上线XMLRPC命令执行逆向工程动态调试漏洞利用代码编写 方法 CVE-2021-3493缓冲器溢出漏洞 学习目标 …...

独立站+TikTok达人:自主营销与创意内容的完美结合

在全球电商市场迅猛发展的今天&#xff0c;独立站和TikTok达人的结合正在创造一种全新的电商营销模式。独立站作为电商平台&#xff0c;其自主性和灵活性为商家提供了广阔的发展空间&#xff1b;而TikTok达人凭借其独特的内容创作能力和庞大的粉丝基础&#xff0c;成为推动销售…...

【启明智显分享】适用于多功能养生壶、茶吧机的2.8寸触摸彩屏解决方案

健康生活理念不断深入人心&#xff0c;多功能养生壶、茶吧机等智能产品成为现代家庭的热门小家电。为推动智能家居个性化、多样化发展&#xff0c;启明智显推出了基于SC05 Plus 2.8寸触摸彩屏的多功能养生壶、茶吧机的解决方案&#xff0c;旨在提升养生壶与茶吧机的用户体验与操…...

WAF绕过技术(PKAV团队)

目录 主流WAF的绕过技术 Web容器的特性 1. IIS+ASP的神奇% 2. IIS的Unicode编码字符 3. HPP(HTTP Parameter Pollution): HTTP参数污染 4. 畸形HTTP请求 Web应用层的问题 1. 多重编码问题 2. 多数据来源的问题 WAF自身的问题 1. 白名单机制 2. 数据获取方式存在缺陷…...

『 Linux 』POSIX 信号量与基于环形队列的生产者消费者模型

文章目录 信号量概念POSIX 信号量基于环形队列的生产者消费者模型基于环形队列的生产者消费者模型编码实现基于环形队列的生产者消费者模型发送任务测试 信号量概念 信号量是一种用于多线程或多进程间同步的机制; 其定义是一个整形变量,本质上信号量可以看成是一个计数器,用来描…...

python中的字符串方法

python中的字符串 举个例子先 name = 貂蝉开大 #声明了一个字符串 print(name) # 打印了一个字符串 print(name[0:1] #输出貂蝉 print(name[2:3] #输出开大 扩展方法 find() # 查找字符串中某个字符的索引 index_ = name.find("貂") print(index_) # 输出 …...

python实现consul的服务注册与注销

我在使用consul的时候主要用于prometheus的consul服务发现&#xff0c;把数据库、虚拟机信息发布到consul&#xff0c;prometheus通过consul拿到数据库、虚拟机信息去采集指标信息。 此篇文章前提是已经安装好consul服务以后&#xff0c;安装consul请参考二进制方式部署consul…...

校园选课助手【2】-重要的登录模块

用户登录模块技术要点&#xff1a; 密码通过MD5加密传输分布式session存储用户登录信息自定义注解进行字段校验自定义拦截器完成登录验证 下面依次给出代码和详细解释&#xff1a; 1.使用 MD5 二次加密用户登录信息&#xff0c;前端先通过密码加上盐进行MD5加密交给服务器&a…...

4章2节:从排序到分组和筛选,通过 R 的 dplyr 扩展包来操作

dplyr是R语言中一个强大且高效的数据处理包,专门设计用于处理数据框(data frames)。它的语法简洁明了,操作高效,尤其适用于大数据集。dplyr提供了一系列函数,使得数据的筛选、变换、聚合和排序等操作变得简单直观。本文将详细介绍dplyr扩展包如何进行数据的排序到分组和筛…...

C语言实现 -- 单链表

C语言实现 -- 单链表 1.顺序表经典算法1.1 移除元素1.2 合并两个有序数组 2.顺序表的问题及思考3.链表3.1 链表的概念及结构3.2 单链表的实现 4.链表的分类 讲链表之前&#xff0c;我们先看两个顺序表经典算法。 1.顺序表经典算法 1.1 移除元素 经典算法OJ题1&#xff1a;移除…...

WSL和Windows建立TCP通信协议

1.windows配置 首先是windows端&#xff0c;启动TCP服务端&#xff0c;用来监听指定的端口号&#xff0c;其中IP地址可以设置为任意&#xff0c;否则服务器可能无法正常打开。 addrSer.sin_addr.S_un.S_addr INADDR_ANY; recv函数用来接收客户端传输的数据&#xff0c;其中…...

Android Gradle开发与应用(一):Gradle基础

文章目录 引言一、Gradle简介二、Gradle基础语法1. 项目结构2. 插件应用3. 仓库与依赖4. 任务&#xff08;Tasks&#xff09; 三、Gradle在Android项目中的深入应用1. 构建变体&#xff08;Build Variants&#xff09;2. 依赖管理3. 自定义构建逻辑 四、Gradle WrapperGradle W…...

Linux多线程服务器编程-1-线程安全的对象生命期管理

对象的生与死不能由对象自身拥有的mutex&#xff08;互斥器&#xff09;来保护. 如何避免对象析构时可能存在的race condi​t​ion&#xff08;竞态条件&#xff09;是C多线程编程面临的基本问题。 对象的销毁可能出现多种竞态条件(race condi​t​ion)&#xff1a; 在即将析构…...

Couchbase 技术详解

文章目录 Couchbase 原理数据模型数据分布数据访问与同步官网链接 基础使用安装与配置数据操作 高级使用数据分片与负载均衡数据索引与查询安全性与权限管理 优点高性能可扩展性高可用性灵活性 总结 Couchbase 是一个高性能、分布式、可扩展的 NoSQL 数据库系统&#xff0c;基于…...

PTE-信息收集

一、渗透测试流程 渗透测试通常遵循以下六个基本步骤&#xff1a; 前期交互&#xff1a;与客户沟通&#xff0c;明确测试范围、目标、规则等。信息收集&#xff1a;搜集目标系统的相关信息。威胁建模&#xff1a;分析目标系统可能存在的安全威胁。漏洞分析&#xff1a;对收集…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...