算法第三章作业
第三章作业题“单调递增最长子序列”分析
1 根据最优子结构性质,列出递归方程式。
a[i] :原问题输入的数组。
b[i] :用来记录从第0个到a[i]的单调递增最长子序列。从0到n初始化为1。
b[i] = b[i-1]+1 ; ( 0<j<i , a[i] > a[i-1] )
2 给出填表法中表的维度、填表范围和填表顺序。
表的维度:用一个一维数组 ( b[i] )就可以来记录从第0个到a[]中第i个数的单调递增最长子序列。
填表范围:从0到n。
填表顺序:从左往右。
3 分析该算法的时间和空间复杂度
时间复杂度:双层循环,因此时间复杂度为 O(n^2)。
空间复杂度:一维数组,因此空间复杂度为 O(n)。
你对动态规划算法的理解
动态规划,是一个用来求解最优解的过程。基本思想也就是将原问题分解成若干个子问题,通过求解子问题来的得到原问题的解。为了节省时间,避免大量的重复的计算,还可以通过一个表来记录已经计算过的解,在需要时可以直接调用已经求过的解,就避免来重复计算。这样看和分而治之的办法很类似,但是和分治法不同的是,动态规划分解得到的子问题不是相互独立的,而是相互联系的。
动态规划问题分为以下四步:
- 找到最优子结构,刻画其结构特征。
- 递归地定义最优解。
- 以自底向上的方式求得最优解。
- 构造最优解。
说明结对编程情况
相比之前会更加的默契
源代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 5 int n; 6 int a[10001]; 7 int dp[10001]; 8 int ans = 0; 9 10 int f() { 11 for (int i=0; i<n; i++) { 12 dp[i] = 1; 13 for (int j=0; j<i; j++) 14 if (a[i] > a[j]) 15 dp[i] = max(dp[i], dp[j]+1); 16 } 17 18 for (int i=0; i<n; i++) 19 ans = max(ans, dp[i]); 20 21 return ans; 22 } 23 24 int main() 25 { 26 cin >>n; 27 for (int i=0; i<n; i++) 28 cin >>a[i]; 29 30 cout <<f() <<endl; 31 32 return 0; 33 }