算法:最长递增子序列、最长公共子串
来源:互联网 发布:小苍零食淘宝店 编辑:程序博客网 时间:2024/06/10 18:28
#include<iostream>#include<cstring>#define MAXSEQUENCE 1000#define MAXDIF 1000using namespace std;void Print_LCS(int (*rec)[100],int a[], int b[], int i, int j);//---------最长递增子序列-----------//动态规划 O(n*n) 递推式:len[i] = max{ len[k]+1 | a[k]< a[i] , 0<=k<i}int LIS(int a[],int n){int len[MAXSEQUENCE];len[0]=1;for(int i=1;i<n;i++){len[i]=1;//此处是O(n),可用二分搜索来对此处改进 B数组,//下标是最大子序列长度,值是最小的最末元素,巧妙!!! (即下面的该函数LIS_bin)for(int j=0;j<i;j++)if(a[j]<a[i]&&len[j]+1>len[i])len[i]=len[j]+1; }int maxlen=0; for(int i=0;i<n;i++) if(len[i]>maxlen) maxlen=len[i];return maxlen;}//动态规划O(nlogn),求最长递增子串的长度更快捷,难以输出最长子串。int LIS_bin(int a[],int n) {int B[MAXSEQUENCE]; int len=1;B[0]=a[0]; //注意此处的赋值,不是B[0]=0; for(int i=1;i<n;i++){int left=0, right=len-1;while(left<=right){ //O(logn) 找到大于等于ai的第一个元素 ,返回时left指向 int m=(left+right)/2;if(B[m]<a[i]) left=m+1;else right=m-1;}B[left]=a[i]; //更新 if(left+1>len) len++; //看是否长度要增大} return len;}//o(n*n),但存储空间从o(n)增大到o(n*maxdis),maxdis为所有元素的最大差值,有没有更好的方法? int LIS_EqualDif(int a[], int n) { n=n;int len[MAXSEQUENCE][MAXDIF]; //当差增较大时,很快存储空间就不能定义了 //求最大差值int MaxVal=a[0], MinVal=a[0];for(int i=1;i<n;i++){if(MaxVal<a[i]) MaxVal = a[i];else if(MinVal>a[i])MinVal = a[i];} int MaxDif = MaxVal - MinVal;memset(len,0,n*(MaxDif+1)*sizeof(int)); for(int i=1;i<n;i++){for(int j=0;j<i;j++){int dis=a[i]-a[j];if(dis>=0) //注意是等差,所以相等也算 len[i][dis] = len[j][dis] + 1;}}int result=0;for(int i=0;i<n;i++)for(int j=0;j<=MaxDif;j++)if(result<len[i][j])result = len[i][j];return result+1;}//---------最长公共子序列-----------//动态规划,O(mn) ,a.length=m, b.length=n int LCS(int a[], int n,int b[],int m){int len[MAXSEQUENCE][MAXSEQUENCE]; //从下标1开始,记录i,j之前的最大长度 for(int i=0;i<n;i++)len[i][0]=0;for(int i=0;i<m;i++)len[0][i]=0;int i,j;for(i=0;i<n;i++){for(j=0;j<m;j++){if(a[i]==b[j]){ //如果相等 len[i+1][j+1]=len[i][j]+1;}else{// 不相等 if( len[i][j+1]>len[i+1][j] )len[i+1][j+1]=len[i][j+1];elselen[i+1][j+1]=len[i+1][j];}}}return len[i][j];}//分治,最长公共子串,O(2^n) ,有太多的重复计算,导致复杂度呈指数级增长 int LCS_recur(int a[], int n, int b[],int m){if(m==0||n==0)return 0;if(a[n-1]==b[m-1]){return LCS_recur(a,n-1,b,m-1)+1;}else{int tmp1=LCS_recur(a,n-1,b,m);int tmp2=LCS_recur(a,n,b,m-1);if(tmp1>tmp2)return tmp1;elsereturn tmp2;} }int main(){loop: int a[MAXSEQUENCE],b[MAXSEQUENCE],n,m;//LISprintf("n: ");scanf("%d",&n);for(int i=0;i<n;i++)scanf("%d",&a[i]);printf("LIS: %d\n",LIS(a,n));printf("LIS_bin: %d\n",LIS_bin(a,n));printf("LIS_EqualDif: %d\n",LIS_EqualDif(a,n));//LCSprintf("m: ");scanf("%d",&m);for(int i=0;i<m;i++)scanf("%d",&b[i]);printf("LCS: %d\n",LCS(a,n,b,m));printf("LCS_recur: %d\n",LCS_recur(a,n,b,m));goto loop; return 0; }
- 算法:最长递增子序列、最长公共子串
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
- 算法之最长递增子序列,最长公共子序列
- 算法之最长递增子序列,最长公共子序列
- 最长公共子串、最长公共子序列、最长递增子序列、最长回文子串
- 求解最大子序列、最长递增子序列、最长公共子串、最长公共子序列
- 最大子序列和、最长递增子序列、最长公共子串、最长公共子序列
- 最大子序列和、最长递增子序列、最长公共子串、最长公共子序列
- 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、
- 最大子序列最长递增子序列最长公共子串最长公共子序列
- 最长递增公共子序列
- 最长公共递增子序列
- 最长公共递增子序列
- 最长公共递增子序列
- 编辑距离,最长公共子序列,最长公共子串,最长递增子序列
- 最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
- 编辑距离,最长公共子序列,最长公共子串,最长递增子序列
- 编辑距离,最长公共子序列,最长公共子串,最长递增子序列
- JAVA学习笔记---集合(Collection)
- 对高性能计算机发展的看法.
- Linux od命令
- sja1000 CAN控制器波特率计算方法详解
- 读《数据挖掘技术(第三版)》-应用于市场营销,销售与客户关系管理 有感
- 算法:最长递增子序列、最长公共子串
- 省赛 双线程dp
- _com_util::ConvertBSTRToString 连接错误
- 下拉树~不断、持续完善中~
- 二叉树
- poj 3349 snowflake 哈希表
- Java对象创建方式及JVM对字符串处理
- 回文字符串
- Java学习笔记(AWT组件 之 按钮)