算法第三章作业
1.单调递增最长子序列
3-2 单调递增最长子序列 (25分)
设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
输入格式:
输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字之间用空格格开
输出格式:
最长单调递增子序列的长度
输入样例:
在这里给出一组输入。例如:
5
1 3 5 2 9
输出样例:
在这里给出相应的输出。例如:
4
代码:
#include <iostream>
using namespace std;
int b[20];
int ans = 1;
void solve(int a[], int n){
for(int i = 0; i < n; i++){
b[i] = 1;
for(int j = 0; j < i; j++)
if(a[i] > a[j])
b[i] = max(b[i], b[j] + 1);
ans = max(ans, b[i]);
}
}
int main(){
int n;
cin >> n;
int a[n];
for(int i = 0; i < n; i++)
cin >> a[i];
solve(a, n);
cout << ans;
return 0;
}
1.1根据最优子结构性质,列出递归方程式
设置了一个b[i]数组,从第一个数开始比较,直至最后一个数。
递归方程式:b[i]=max{b[j]}+1
1.2给出填表法中的表的维度、填表范围和填表顺序
表的维度:一维,因为数组是一维数组
填表范围:0<=j<i
填表顺序:自左而右
1.3分析该算法的时间和空间复杂度
时间复杂度:因题目有要求而且代码中有双重循环比较,所以为O(n*n)
空间复杂度:O(n),用到了一个一维数组来存放数据
2.对动态规划算法的理解
动态规划算法的基本思想是将待求解问题分成若干个子问题,通过求解子问题,来得到原问题的解;适用于动态规划算法求解的问题经过分解后得到的问题往往不是互相独立的。
动态规划算法的第一步通常是要刻画最优解的结构,接着利用最优子结构性质来递归地从子问题的最优解逐步构造出整个问题的最优解,然后以自底向上的方式计算最优值,最后根据计算最优值时得到的信息,构造最优解。动态规划算法需要考虑的是子问题的重叠性质,解决方式即每个子问题都只求解一次并保存在表格中,等要用的时候直接访问表格,得到所要的子问题的解。
3.结对编程情况
这一次结对编程的题目是最低通行费,因为一开始在做题的时候我对动态规划算法还是比较陌生的,而且还没掌握好方法,但是和伙伴在分析题目,结合老师所讲的代码之后,我们很快就把递归方程式写出来了,然后就可以按照递归方程式打代码了。在这个过程中给我的感受是讨论的力量是很大的,而且讨论可以让我在还不太熟悉知识点的情况下,慢慢地让知识点进脑子里,所以我觉得结对编程可以提高学习效率,同时学习他人不同的思考方式来拓宽自己的思维。