第三章单调递增最长子序列
1.
7-1 单调递增最长子序列
设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
输入格式:
输入有两行: 第一行:n,代表要输入的数列的个数 第二行:n个数,数字之间用空格格开
输出格式:
最长单调递增子序列的长度
输入样例:
在这里给出一组输入。例如:
5
1 3 5 2 9
输出样例:
在这里给出相应的输出。例如:
4
代码如下:
#include <iostream> #include <cstdio> using namespace std; int main() { int i,j,n,r=1; cin>>n; int dp[n],a[n]; for(i=1;i<=n;i++) { cin>>a[i]; dp[i]=1; //初始化 } for(i=1;i<=n;i++) { for(j=1;j<i;j++) //遍历所有a[i]前的元素 { if(a[j]<a[i]) // dp[i]=max(dp[i],dp[j]+1); } r=max(r,dp[i]); //更新 } cout<<r; return 0; }
思路分析:
先定义dp[i]: 以ai为末尾的最长上升子序列的长度。以ai结尾的上升子序列是:
1° 只包含ai的子序列
2° 在满足j<i且aj<ai的以aj结尾的上升子列末尾,追加上ai后得到的子序列
这二者之一。这样就能得到如下递推关系:
dp[i]=max{1, dp[j]+1 | j<I 且aj<ai},时间复杂度为O(n2),。
2. 对动态规划算法的理解
感觉对于动态规划更像是把一个大问题拆解成一堆小问题,然后在解决这些小问题的时候避免了重复计算的过程,每个问题只计算一次,自底向上地求出原问题的解。
3.说明结对编程情况
目前来看结对编程的时候会出现较大分歧,然后出现多种解题想法但最后无法实现而被否决。打击自信心确实有,但更希望自己能更快学到更多。