最长递增子序列(三种方法求解)
来源:互联网 发布:淘宝怎么加入返利网 编辑:程序博客网 时间:2024/05/21 11:13
最长递增子序列,顾名思义是找到序列中递增序列的最长长度。
基本概念
设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。求最大的m值。
方法一:排序并使用LCS求解
基本思想:排序后原序列成为递增的序列,那么只需要找到和原来序列的最长公共子序列即可
#include<stdio.h>#include<stdlib.h>int a[105];int b[105];int dp[105][105]={1};int cmp( const void *a, const void *b){return *(int *)a - *(int *)b;}int max(int a,int b){return a>b?a:b;}int main(){int n;int i,j;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&a[i]);b[i]=a[i];}qsort(b,n,sizeof(b[0]),cmp);for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(a[i-1]==b[j-1])dp[i][j]=dp[i-1][j-1]+1;elsedp[i][j]=max(dp[i-1][j],dp[i][j-1]);}printf("%d\n",dp[n-1][n-1]);return 0;}
方法二:动态规划求解
基本思想:找到当前位置以前的最长序列,接着再拿当前位置与已存序列比较,看是否可以加入序列,那么到最后一个数时 dp【n】已经更新为最长的递增子序列
#include<stdio.h>#include<string.h>int max(int a,int b){return a>b?a:b;}int main(){char dp[105];memset(dp,1,strlen(dp));int a[105];int n;int i;scanf("%d",&n);for( i=0;i<n;i++)scanf("%d",&a[i]);for( i=1;i<n;i++)for(int j=0;j<i;j++)if(a[j]<a[i]&&dp[j]>dp[i]-1)dp[i] = dp[j]+1;printf("%d",dp[n-1]);return 0;}
方法三:dp加二分
思想:在方法二中,每一次都要将到当前位置以前所有的序列顺序查找一遍,这样加入序列有序则可以使用二分查找来降低时间复杂度,所以想到,将每一个递增序列的最末尾元素存到dp数组中,那样可以根据每一次更新来构造一个递增的dp数组,之后进行二分查找来判断当前位置可以为哪一个递增序列的末尾元素,换言之,找到每一个末尾元素,那么递增子序列会增加,这样扫完所有的元素就可以找到最长的子序列
#include<stdio.h>int main(){int a[105];int dp[105];int len = 1;int n;int mid;int i,j;scanf("%d",&n);for(i=0;i<n;i++)scanf("%d",&a[i]);dp[0]=-1;//默认输入数字全为正数dp[1]=a[0];//长度为一的子序列先默认成第一个数for(i=1;i<n;i++){int r = 0;//由于将最长子序列的末尾元素进行打表,所以末尾元素越小越好//那么,不同长度的子序列的末尾元素则递增有序,这样每扫到一个元素,找到合适的序列长度//看是否可以当作末尾元素,dp数组有序则利用二分搜索。int l = len;while(r<=l){ mid = (r + l)/2; if(dp[mid]<=a[i]) r=mid+1;//找到合适的位置进行更改序列的大小。找到可改变的序列的大小 else l=mid-1;}dp[r] = a[i];//找到可改变的位置,将长度为r的最后一个元素改为a[i];if(r>len)len=r;//更新当前最长的递增子序列}printf("%d\n",len);return 0;}
上面三种方法的时间复杂度分别为
方法一:O(n^2)+O(nlogn)=O(n^2)
方法二:O(n^2)
方法三:O(nlogn)
0 0
- 最长递增子序列(三种方法求解)
- 最长递增子序列(LIS)的三种求解方法
- 最长递增子序列(LIS)求解
- 最长递增子序列求解
- 三种寻找最长递增(减)子序列的方法【LIS】
- 最长递增子序列问题的求解(LIS)
- 关于最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列问题的求解(LIS)
- 使用动态规划求解最长递增子序列(LIS)
- 最长递增子序列问题的求解
- 最长递增子序列问题的求解
- zz:最长递增子序列的求解
- 最长递增子序列问题的求解
- 最长递增子序列问题的求解
- 最长递增子序列问题的求解
- poj-2983 Is the Information Reliable? 差分约束+判负环
- 从HelloWorld来看Go语言的基本面貌
- oc的基础知识
- JMeter
- 关于我,关于本blog,关于本blog的正确打开方式
- 最长递增子序列(三种方法求解)
- 曹操让张辽一战成名的取胜密函
- mysql 语句中带变量
- SQL连接查询语句(内、外、交叉和合并查询)
- Activity间传递自定义类型对象
- 原来是这样的,我明白了,
- win7 32位设置JDK1.6环境变量的方法
- 相当漂亮的主题
- Autolayout自动布局2