第三章单调递增最长子序列

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.说明结对编程情况

  目前来看结对编程的时候会出现较大分歧,然后出现多种解题想法但最后无法实现而被否决。打击自信心确实有,但更希望自己能更快学到更多。

posted on 2020-11-01 04:52  lzchenjin  阅读(194)  评论(0编辑  收藏  举报

导航