动态规划之最长单调递增子序列
东 华 大 学
《算法设计分析与综合实践》分析题作业
学生姓名:曹晨 学号:171310402
请勿抄袭或转载
- 作业题目
设计一个O(n² )时间的算法,找出由n个数组成的序列的最长单调递增子序列。
- 解题过程(针对算法设计题)
- 解题思路/算法设计思路。
记f(x)为ax结尾的最长递增子序列的长度,那么答案就是max{f(x)}。
考虑比x小的每一个数k(0<=k<x):我们把ax接在ak的后面,肯定能构造一个以ax结尾的上升子序列,长度比ak以结尾的上升子序列大1,
所以如果有ax>ak,那么f(x)可以取f(k)+1。
- 写出算法描述(
算法描述如下:
1 #include <iostream>
2
3 using namespace std;
4
5 int LSI(int *a,int n)//计算最长递增子序列的值的函数
6 {
7 int f[n];
8 for(int i=0;i<n;i++)
9 {
10 f[i]=1;
11 }//以a[i]结尾的最长单调子序列初始化为1,即它本身
12 for(int i=1;i<n;i++)
13 {
14 for(int j=0;j<i;j++)
15 {
16 if(a[j]<a[i])
17 {
18 f[i]=max(f[i],f[j]+1);
19 }//如果i前面j的值小于i的值,那么i的最长递增子序列可以取k的最长递增子序列的数值加1
20 }
21 }
22 int length=0;
23 for(int i=0;i<n;i++)
24 {
25 length=max(length,f[i]);
26 }//找到所有单调递增子序列中的最大值
27 return length;//返回最长单调递增子序列
28 }
29 int main()
30 {
31 int n;
32 cin>>n;//元素的个数
33 int a[n];
34 for(int i=0;i<n;i++)
35 {
36 cin>>a[i];
37 }//存放元素
38 cout<<LSI(a,n);//调用求最长递增子序列的函数,并输出该值
39 return 0;
40 }
输入:8
1 5 3 4 6 9 7 8
输出:
- 算法分析:
时间复杂度:
代码中用到了一个两个for循环的嵌套(第12行-第21行),所以时间复杂度为O(n² )。
空间复杂度:
代码中申请了两个n长度的数组,分别用来存放元素和在以第i个元素为结尾时最长递增子序列的值,所以空间复杂度为O(n)。