最长公共子序列LCS+最长递增子序列LIS+最长递增公共子序列LICS
时间:2020-04-11
本文章向大家介绍最长公共子序列LCS+最长递增子序列LIS+最长递增公共子序列LICS,主要包括最长公共子序列LCS+最长递增子序列LIS+最长递增公共子序列LICS使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
最长公共子序列(LCS):两个串s1和s2中取出若干有序位置的字符,使得取出的两个字符串相同的长度的最大值就是LCS
最长递增子序列(LIS):S的子序列,其中各元素按索引严格单调递增
最长公共递增子序列(LCIS):上面两者的结合,参考博客:https://blog.csdn.net/wall_f/article/details/8279733
最长上升子序列的O(n^2)复杂度算法,算法的优势在于可以保存算法的转移,可以得出最后的序列。
代码如下:
1 #include<iostream> 2 using namespace std; 3 #define maxn 100 4 int n; 5 // 20 17 2 3 4 1 4 6 9 1 1 2 3 4 9 87 21 23 331 31 44 6 // 10 1 1 1 1 1 2 2 2 3 3 7 int a[maxn]; 8 int dp[maxn],from[maxn]; 9 void print (int pos) 10 { 11 if(!pos)return; 12 print(from[pos]); 13 cout<<a[pos]<<' '; 14 } 15 int main() 16 { 17 cin>>n; 18 for(int i=1;i<=n;i++)cin>>a[i]; 19 for(int i=1;i<=n;i++) 20 { 21 dp[i]=1;//以i为终止位置的最长上升子序列的长度 22 for(int j=1;j<i;j++) 23 { 24 if(a[i]>a[j]&&dp[i]<dp[j]+1) 25 { 26 dp[i]=dp[j]+1; 27 from[i]=j;//使dp[i]改变的最后一个位置 28 } 29 } 30 } 31 int ans=1,pos=1; 32 for(int i=1;i<=n;i++) 33 { 34 if(dp[i]>ans) 35 { 36 ans=dp[i];//记录len改变的最后一个位置 37 pos=i; 38 } 39 } 40 cout<<ans<<endl; 41 print(pos); 42 }
最长上升子序列的O(nlogn)算法, 中间结果无法保存,只能知道最长上升子序列的长度。其中加上一个辅助数组,数组的长度表示的是最长上升子序列的长度,数组中第i个位置保存的数是长度为i的最长上升子序列的末位最小元素,利用了贪心的思想,因为末尾的元素值越小的话留给下一个元素更新的余地就会更大。由于长度为n-1的最长上升子序列的末位元素一定是小于长度为n的最长上升子序列的末位元素,所以辅助数组的元素一定是有序的。
代码如下:
1 #include<iostream> 2 using namespace std; 3 #define maxn 100 4 #define INF 0x7ffffff 5 int n,l,r; 6 int a[maxn],dp[maxn];//dp[i]表示长度为i的最长上升子序列的末位元素最小值 7 int main() 8 { 9 cin>>n; 10 for(int i=1;i<=n;i++) 11 { 12 cin>>a[i]; 13 dp[i]=INF; 14 } 15 dp[1]=a[1]; 16 int len=1; 17 for(int i=2;i<=n;i++) 18 { 19 int mid; 20 l=0,r=len; 21 if(a[i]>dp[len])dp[++len]=a[i]; 22 else 23 { //二分查找 ,查找第一个大于a[i]的位置 24 while(l<r) 25 { 26 mid=(l+r)/2; 27 if(dp[mid]>a[i])r=mid; 28 else { 29 l=mid+1; 30 } 31 } 32 } 33 dp[l]=min(dp[l],a[i]); 34 } 35 cout<<len<<endl; 36 }
最长公共子序列算法如下:(包括对路径的保存)
1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 int dp[1000][1000]; 5 int main() 6 { 7 string a,b; 8 while(cin>>a>>b) 9 { 10 for(int i=1;i<=a.size();i++) 11 for(int j=1;j<=b.size();j++) 12 { 13 if(a[i-1]==b[j-1])dp[i][j]=dp[i-1][j-1]+1; 14 else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 15 } 16 17 char path[1000]; 18 for(int aa=a.size(),bb=b.size(),num=1;aa>=1&&bb>=1;) 19 { 20 if(a[aa-1]==b[bb-1]) 21 { 22 path[num++]=a[aa-1]; 23 aa--,bb--; 24 } 25 else 26 { 27 if(dp[aa-1][bb]>dp[aa][bb-1]) 28 aa--; 29 else bb--; 30 } 31 } 32 cout<<dp[a.size()][b.size()]<<endl; 33 for(int i=dp[a.size()][b.size()];i>=1;i--) 34 cout<<path[i]<<" "; 35 cout<<endl; 36 } 37 return 0; 38 }
最长公共上升子序列算法:
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 using namespace std; 5 6 int max(int a,int b) 7 { 8 return a>b?a:b; 9 } 10 11 int a[1010],b[1010]; 12 int f[1010],n,m; 13 14 int LCIS() 15 { 16 int i,j,MAX; 17 memset(f,0,sizeof(f)); 18 for(i=0;i<n;i++) 19 { 20 MAX=0; 21 for(j=0;j<m;j++) 22 { 23 if(a[i]>b[j])MAX=max(MAX,f[j]); 24 if(a[i]==b[j])f[j]=MAX+1; 25 } 26 } 27 int ans=0; 28 for(i=0;i<m;i++) 29 ans=max(ans,f[i]); 30 return ans; 31 } 32 33 int main() 34 { 35 int t,i,j; 36 scanf("%d",&n); 37 for(i=0;i<n;i++) 38 { 39 scanf("%d",&a[i]); 40 } 41 scanf("%d",&m); 42 for(j=0;j<m;j++) 43 { 44 scanf("%d",&b[j]); 45 } 46 printf("%d\n",t=LCIS()); 47 if(t) 48 printf("\n"); 49 for(int i=0;i<t;i++)cout<<f[t]<<endl; 50 return 0; 51 }
原文地址:https://www.cnblogs.com/randy-lo/p/12679166.html
- maven build时报错Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
- Spring Cloud(九)高可用的分布式配置中心 Spring Cloud Config 集成 Eureka 服务
- Spring Cloud(八)高可用的分布式配置中心 Spring Cloud Config
- 用Raspberry Pi Zero打造「即插即用」的Web服务器
- Spring Cloud(七)服务网关 Zuul Filter 使用
- 基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理
- Spring Cloud(六)服务网关 zuul 快速入门
- Docker Registry Server 搭建,配置免费HTTPS证书,及拥有权限认证、TLS 的私有仓库
- Ubuntu 17.04 编译安装 Nginx 1.9.9 配置 https 免费证书
- 基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用
- Docker Image 解决镜像无法删除的问题
- Docker Hub 仓库使用,及搭建 Docker Registry
- 基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用
- Docker 容器操作
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 偿还技术债(1)-EventBus源码详解
- 两万六千字带你Kotlin入门
- 从源码看 Jetpack(7)-SavedStateHandle源码详解
- 从源码看 Jetpack(6)-ViewModel源码详解
- linux配置c++11编译环境
- Java 多线程编程(聊聊线程池)
- Java 多线程编程(“锁”事碎碎念)
- Spring Cloud Alibaba技术栈(下)
- Electron安装过程深入解析(读完此文解决Electron安装失败导致的无法启动,无法打包的问题)
- Kafka中副本机制的设计和原理
- Cocoapods更新出错
- 用 Wolfram 语言映射美国的山火
- Mathematica在中学数学教与学中的应用
- 总结一些ES不常用的filter
- 如何将炫酷的报表直接截图发送邮件——在Superset 0.37使用Schedule Email功能