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

【线性dp必学四道题】线性dp四道经典例题【最长上升子序列】、【最长公共子序列】、【最长公共上升子序列(maxv的由来)】【最长公共子串】

【最长上升子序列】、【最长公共子序列】、【最长公共上升子序列】

    • 最长上升子序列
        • f[i] 表示以i结尾的最长子序列
    • 最长公共子序列
        • f[i][j] 表示 a前i 和 b前j个 最长公共长度
    • 最长公共上升子序列
        • f[i][j]代表所有a[1 ~ i]和b[1 ~ j]中以b[j]结尾的公共上升子序列的集合
    • 最长公共子串

最长上升子序列

在这里插入图片描述

f[i] 表示以i结尾的最长子序列

由于我们遍历到i时候
我们需要比较i前面的数据

我们发现如果i 大于 j

那么i就可以拼接在 j 后面

如果f[j] 就是j最长的了
那就
f[i] = f[j] + 1的长度
所以
f[i] 表示以i结尾的最长子序列

#include<iostream>using namespace std;const int N = 1100;int a[N];
int f[N];
int res = 0;
int n;int main()
{cin >> n;for(int i = 1; i <= n; i++) cin >> a[i];a[0] = -0x3f3f3f3f;for(int i = 1; i <= n; i++){for(int j = 0; j <= i ; j++){if(a[j] < a[i])f[i] = max(f[i],f[j]+1);res = max(res,f[i]);}}cout << res;return 0;
}

最长公共子序列

在这里插入图片描述

f[i][j] 表示 a前i 和 b前j个 最长公共长度

#include<iostream>using namespace std;const int N = 1010;int f[N][N];
char a[N],b[N];
int n,m;int main()
{cin >> n >> m;cin >> a+1 >> b+1;for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++){if(a[i]==b[j]){f[i][j] = f[i-1][j-1]+1;}else{f[i][j] = max(f[i-1][j],f[i][j-1]);}}}cout << f[n][m];return 0;
}

最长公共上升子序列

在这里插入图片描述

f[i][j]代表所有a[1 ~ i]和b[1 ~ j]中以b[j]结尾的公共上升子序列的集合

这道题如何理解?

  1. 记住f[i][j] 表示什么
  2. 当b的j和i 相等时,我们常规思路是就在b数组中按着第一道题的逻辑 循环遍历之前的值,但是这样是麻烦的。我们需要一种方法,不需要遍历就知道之前的最大值,可以定义一个变量maxv,如果i和j相等,直接等于maxv,如果不相等,那么f[i][j] = f[i-1][j]
  3. 如果a[i]>b[j]
    那么maxv = max(maxv,f[i-1][j]+1);

maxv的由来
在这里插入图片描述

#include<iostream>using namespace std;const int N = 3030;int f[N][N];
int a[N],b[N];
int n;int main()
{cin >> n;for(int i = 1; i <= n; i++) cin >> a[i];for(int i = 1; i <= n; i++) cin >> b[i];for(int i = 1; i <= n; i++){int maxv = 1;for(int j = 1; j <= n; j++){f[i][j] = f[i-1][j];if(a[i]==b[j]){f[i][j] = maxv;}if(a[i]>b[j])maxv = max(maxv,f[i-1][j]+1);}}int ans = 0;for(int i = 0; i <= n; i++){ans = max(f[n][i],ans);}cout << ans;return 0;
}

最长公共子串

在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <cstring>
using namespace std;const int N = 1e4 + 10;
char str1[N], str2[N];int f[N][N];//注意空间限制为256MB,即为2^(8 + 20) = 2^28个字节,
//而一个int型变量占4个字节,那么最多有2^26个int变量,大约为64000000个变量,而此时定义f[N][N]最多有大于1e8个变量,会爆内存
//更何况还有存字符串的空间int main()
{cin >> str1 + 1 >> str2 + 1;    int len1 = strlen(str1 + 1), len2 = strlen(str2 + 1);int res = 0;for (int i = 1; i <= len1; i++){//如果最后一位为数字if (str1[i] >= '0' && str1[i] <= '9'){for (int j = 1; j <= len2; j++)f[i][j] = 0;continue;    }for (int j = 1; j <= len2; j++){//如果最后一位相同且不为数字if (str1[i] == str2[j])f[i][j] = f[i - 1][j - 1] + 1;else f[i][j] = 0;res = max(res, f[i][j]);}}cout << res << endl;return 0;
}

观察我们在状态计算的过程,第i层循环的值,仅与第i-1层循环的值有关
我们可以联想到01背包的优化,利用滚动数组来简化空间复杂度
既然要用到删除一维空间的优化方法,一定要注意:
二维中:f[i][j] = f[i - 1][j - 1] + 1;
在一维中,由于f[j] = f[j - 1],小的j已经被更新,那么就不是上一层(i-1)的数据了
所以必须从大到小遍历

#include <iostream>
#include <cstring>
using namespace std;const int N = 1e4 + 10;
char str1[N], str2[N];int f[N];int main()
{cin >> str1 + 1 >> str2 + 1;    int len1 = strlen(str1 + 1), len2 = strlen(str2 + 1);int res = 0;//用于保存答案for (int i = 1; i <= len1; i++){//如果最后一位为数字if (str1[i] >= '0' && str1[i] <= '9'){for (int j = 1; j <= len2; j++)f[j] = 0;continue;    }for (int j = len2; j >= 1; j--){//如果最后一位相同且不为数字if (str1[i] == str2[j])f[j] = f[j - 1] + 1;else f[j] = 0;res = max(res, f[j]);}}cout << res << endl;return 0;
}
http://www.lryc.cn/news/90140.html

相关文章:

  • 追寻幸福:探索幸福的关键特征和行为
  • Redis-02-集群
  • 【2023 · CANN训练营第一季】MindSpore模型快速调优攻略 第三章——MindSpore云上调试调优
  • python笔记17_实例演练_二手车折旧分析p2
  • android 12.0长按Power弹出关机对话框去掉屏幕截图和紧急呼救功能
  • 2023年下半年软考高级需要报班吗?
  • 使用WordPress提高企业敏捷性
  • SSM编程---Day 07
  • Seata术语
  • 【Axure教程】通过文本框维护下拉列表选项
  • 【C++】基础知识--输入/输出(5)
  • 经典文献阅读之--PIBT(基于可见树的实时规划方案)
  • SAP-MM-计算方案字段解析
  • go-gf框架两个表以事务方式写入示例
  • 2023-5-31第三十一天
  • 什么是MQTT?mqtt协议和http协议区别
  • 平台使用篇 | 批处理(bat)脚本使用教程(四)
  • 接口的讲解
  • G0第21章 :gin框架介绍、RESTful API、Gin渲染
  • python list,dict操作
  • 我有一个页面a,在页面a中调用了一个组件,然后组件中要切换页面a的一块区域,该怎么实现?
  • ChatGPT唤醒AI游戏:AIGC持续走深,游戏或成AI最佳抓手
  • 远程服务和web服务和前端,三方通过socket和websocket进行双向通信传输数据
  • Linux 网络基础(2)应用层(http/https协议、请求格式、响应格式、session、cookie、加密传输)
  • 解决sshfs挂载报错
  • 由于过多的连接错误而被 MySQL服务器 阻止
  • Go语言实现JDBC
  • ubuntu修改环境变量的几种方法
  • 基于html+css的图展示95
  • 数据库基础——5.运算符