dp求解各种子串子序列
注:dp可能并不是求解该这些问题的最优算法,这里只是做一个dp 算法的简介。
概念
定义:假设现有一个 string = abcdefghijklmn
最长连续子串:要求在原序列中连续,比如 str = abcd、fghijklm都是valid substring
最长连续子序列:相对顺序在原序列中不变即可;比如 str = afgh、dfkn等等都是valid subsequence
说完了上面的定义;下面来说一说怎么用dp求解最长连续子串和最长连续子序列;既然用到了dp 的方法求解,就要找出相关的状态转移方程。
最长上升子序列
#include <bits/stdc++.h>
using namespace std;
const int maxn=3e4+10;
int a[maxn],b[maxn],n;
int dp[maxn],ans; //dp[i]表示前i个的最长上升子序列
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
dp[i]=1;
for(int j=1;j<i;++j){
if(a[j]<a[i]&&b[j]<b[i]) dp[i]=max(dp[i],dp[j]+1);
ans=max(ans,dp[i]);
}
}
printf("%d\n",ans);
system("pause");
}
最长连续子串
递推方程:
int f[maxn][maxn];
int solve(char *x, char *y)
{
int ans=0;
int lenx=strlen(x);
int leny=strlen(y);
for (int i=0;i<lenx;i++)
{
for (int j=0;j<leny;j++){
if (x[i]!=y[j]) f[i][j]=0;
else if(x[i]==y[j]) f[i][j]=f[i-1][j-1]+1;
ans=max(ans,f[i][j]);
}
}
return ans;
}
最长公共子序列
状态转移方程:
模板(花里胡哨的dp请忽略,网上版本,也可成二维数组):
int dp[maxn][maxn]; //a[1]~a[i]与b[1]~b[j]的最长公共子序列
int solve(int n,int m)
{
for (int i=0;i<=n;i++) dp[i][0] = 0;
for (int i=0;i<=m;i++) dp[0][i] = 0;
for (int i=1;i<=n;i++){ //n,m分别为两个数组的长度
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-1][j],dp[i][j-1]);
}
}
return dp[n][m];
}
最长公共上升子序列
dp[i][j]的含义同最长公共子序列;
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn=3e3+10;
int a[maxn],b[maxn];
int dp[maxn][maxn]; //表示a[1]~a[i]与b[1]~b[j]且以b[j]为结尾的最长上升公共子序列
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(a[i]==b[j]){
dp[i][j]=1;
for(int k=1;k<j;++k){
if(b[k]<a[i]) dp[i][j]=max(dp[i][j],dp[i-1][k]+1);
}
}
else dp[i][j]=dp[i-1][j];
}
}
int ans=0;
for(int i=1;i<=n;++i) ans=max(ans,dp[n][i]);
printf("%d\n",ans);
system("pause");
}
上面是未优化前的代码;起代码复杂度未O(n^3);其中的k循环可以被优化;优化后时间复杂度为O(n^2),看代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int maxn=3e3+10;
int a[maxn],b[maxn];
int dp[maxn][maxn]; //表示a[1]~a[i]与b[1]~b[j]且以b[j]为结尾的最长上升公共子序列
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
int maxv=1;
for(int j=1;j<=n;++j){
dp[i][j]=dp[i-1][j];
if(a[i]==b[j]) dp[i][j]=max(dp[i][j],maxv);
if(b[j]<a[i]) maxv=max(maxv,dp[i][j]+1);
}
}
int ans=0;
for(int i=1;i<=n;++i) ans=max(ans,dp[n][i]);
printf("%d\n",ans);
system("pause");
}
dp求解各种子串子序列的更多相关文章
- DP——最长上升子序列(LIS)
DP——最长上升子序列(LIS) 基本定义: 一个序列中最长的单调递增的子序列,字符子序列指的是字符串中不一定连续但先后顺序一致的n个字符,即可以去掉字符串中的部分字符,但不可改变其前后顺序. LIS ...
- HDU 1087 简单dp,求递增子序列使和最大
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- hdu 1025 dp 最长上升子序列
//Accepted 4372 KB 140 ms //dp 最长上升子序列 nlogn #include <cstdio> #include <cstring> #inclu ...
- LeetCode OJ 322. Coin Change DP求解
题目链接:https://leetcode.com/problems/coin-change/ 322. Coin Change My Submissions Question Total Accep ...
- 动态规划(Dynamic Programming, DP)---- 最大连续子序列和
动态规划(Dynamic Programming, DP)是一种用来解决一类最优化问题的算法思想,简单来使,动态规划是将一个复杂的问题分解成若干个子问题,或者说若干个阶段,下一个阶段通过上一个阶段的结 ...
- uva 10069 Distinct Subsequences(高精度 + DP求解子串个数)
题目连接:10069 - Distinct Subsequences 题目大意:给出两个字符串x (lenth < 10000), z (lenth < 100), 求在x中有多少个z. ...
- 算法练习--- DP 求解最长上升子序列(LIS)
问题描写叙述: 对于2,5,3,1,9,4,6,8,7,找出最长上升子序列的个数 最长上升子序列定义: 对于i<j i,j∈a[0...n] 满足a[i]<a[j] 1. 找出DP公式:d ...
- 洛谷 P1020 导弹拦截(dp+最长上升子序列变形)
传送门:Problem 1020 https://www.cnblogs.com/violet-acmer/p/9852294.html 讲解此题前,先谈谈何为最长上升子序列,以及求法: 一.相关概念 ...
- HDU 4632 Palindrome subsequence(区间DP求回文子序列数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632 题目大意:给你若干个字符串,回答每个字符串有多少个回文子序列(可以不连续的子串).解题思路: 设 ...
随机推荐
- 在x64的Ubuntu系统下安装64bit的交叉编译工具aarch64-linux-gnu-gcc【转】
sudo apt-cache search aarch64 查看哪些版本可以安装: sudo apt--aarch64-linux-gnu 安装一个gcc开头的5版本的支持64bit ARM linu ...
- rabbitmq 命令行与控制台
命令行和管控台 rabbitmqctl stop_app 关闭应用 rabbitmqctl start_app 打开应用 rabbitmqctl status 节点状态 rabbitmqctl add ...
- 计算几何-poj2451-HPI
This article is made by Jason-Cow.Welcome to reprint.But please post the article's address. 题意,求半平面交 ...
- 优化 : Oracle数据库Where条件执行顺序 及Where子句的条件顺序对性能的影响
.Oracle数据库Where条件执行顺序: 由于SQL优化起来比较复杂,并且还会受环境限制,在开发过程中,写SQL必须必须要遵循以下几点的原则: 1.ORACLE采用自下而上的顺序解析WHERE子句 ...
- 003 CSS汇总
字体属性:(font) 大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 {font-style: obl ...
- JDBC 基础用法学习
JDBC概述 java 数据库链接,sun公司退出的 java 访问数据库的标准规范接口 是一种用于执行SQL语句的 java API 可以作为多种关系数据库提供统一接口 是一组 java 工具类和接 ...
- html input file 设置文件类型
解决方案: 使用 input 的 accept 属性指定接受文件类型 -----------更新--------------- 之前的代码有个缺点,打开文件窗口时会自动筛选文件夹下所有符合设定类型的文 ...
- 【做题笔记】P2251 质量检测
一看题就知道是线段树裸题了.可是,对于每个 \(i\) ,对应的 \(Q\) 序列的下标是多少呢?应该查询的区间又是什么呢? 找规律: \(i\ \ \ \ \ \ \ \ m\) \(1\ \Rig ...
- 基于jenkins自动打包并部署docker环境及PHP环境
- Centos6.10-FastDFS-存储器Http配置
Centos610系列配置 1.准备配置 cd /opt/download/fastdfs-master/confcp http.conf /etc/fdfs/http.confcp mime.typ ...