第三章作业
3-2 单调递增最长子序列
1.设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字之间用空格格开。最长单调递增子序列的长度
解决方法:先排序,再求最大公共子序列。
递归方程式:
c[i][j]=0 i>0;j=0;
=c[i-1][j-1]+1 i,j>0;a[i]=b[i];
=max{ c[i][j-1] , c[i-1][j] } i , j>0;a[i] != b[i];
这是一个二维数组,c[i][j]代表从a[1]到a[i]与从b[1]到b[j]的最长公共子序列的长度,首先从第一行开始,由左往右填表,比较c[i][j]的左边和上边,将较大值赋给c[i][j] 。直到填满右上三角。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void LCSLength(int n,int *a,int *b,int **c,int **d) { int i,j; for(i=1;i<=n;i++) c[i][0]=0; for(i=1;i<=n;i++) c[0][i]=0; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(a[i]==b[j]) { c[i][j]=c[i-1][j-1]+1; d[i][j]=1; } else if(c[i-1][j]>=c[i][j-1]) { c[i][j]=c[i-1][j]; d[i][j]=2; } else { c[i][j]=c[i][j-1]; d[i][j]=3; } } } }
嵌套了两个for循环,本题目两个序列长度都是n, 所以时间复杂度为O(n^2);
用到了二维数组填表,所以空间复杂度为S(n)=n^2
动态规划算法虽然也是将问题分成若干个子问题进行求解,但因为需要避免子问题的重复求解,所算法效率上还是比分治法要好,但同时对抽象思维能力和数学逻辑能力的要求就要比使用分治法的高,分治法适用的场景问题也比较简单,有时候一个递归代码就搞定了。动态规划算法力求低复杂度算出最优解,用处很大,后续需要重新做题或另外找题目巩固加强。
结对编程:
原本刚开始是我的同伴作为编程主力,我则提供一些建议,现在随着能力的加强,我也能够有更多的参与度,这样两个人带着不完全相同的想法,互相讨论、实践、验证、解决,效率确实会比一个人高。也能避免当一个人遇到困难而产生惰性。