算法第三章作业
3-2 单调递增最长子序列 (25分)
设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
输入格式:
输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字之间用空格格开
输出格式:
最长单调递增子序列的长度
输入样例:
在这里给出一组输入。例如:
5
1 3 5 2 9
输出样例:
在这里给出相应的输出。例如:
4
递归方程:b[i] = max( b[j]+1 , b[i])
具体代码如下:
#include <iostream> using namespace std; int a[100]; int LMax(int n) { int b[100]; for(int i=0;i<100;i++) b[i]=1; int max = 0; for (int i = 2; i <= n; i++) { int k = 0; for (int j = 1; j < i; j++) { if (a[j] <= a[i] && k < b[j]) { k = b[j]; b[i]++; } if (max < b[i]) { max = b[i]; } } } return max; } int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } cout << LMax(n); }
填表的维度为一维数组,填表范围在0-i,自前往后填表。
第一层循环遍历了整个数组,第二层循环又将每个元素作为扫描的终点,故时间复杂度为O(n^2),空间复杂度为O(1)。
对动态规划算法的理解:要使用动态规划的方法,首先要找到该问题最底层的通解,再嵌套地从这些子问题的解得到原问题的解。由于子问题可能会被重复计算多次,所以我们使用一个表记录子问题的答案,在计算问题之前先查表,若其子问题已经被计算过则直接使用表中的数据即可,相较于分治法节省了大量时间开销。
结对编程情况:在结对编程中有时候会遇到两个人都难以解答的问题,在上网搜索相关资料后可以根据自己的理解向对方讲出解题的大致思路和想法,即使是面对相同的代码也能有不同的理解。我认为这样很有利于拓展思维方式,跳出惯性思维。