题解 | #最长上升子序列(一)#

最长上升子序列(一)

http://www.nowcoder.com/practice/5f65ccbb025240bd8458eb6479c2612e

这是一道动态规划题目。将其分解为子问题,即分解成求解n个 以0到n-1下标的数为结尾的子序列的最大长度的问题。
可以用一个dp数组保存每个数做结尾时对应的最大长度。
假设一个以第i个元素arr[i]结尾的子序列Si,那么Si的长度是由i在Si中的前一个元素arr[j]决定的,Si的长度就等于Sj的长度加一。

这前面一个数arr[j]必须要满足两个条件:

  • arr[j]<arr[i],这样才能构成严格上升
  • dp[j]的值在i之前的所有dp中最大,这样我们求的才是最大长度。

using namespace std;

int main(){
    int n;
    cin>>n;
    vector<int> arr(n);
    for(int i=0;i<n;i++)
        cin>>arr[i];
    vector<int> dp(n,1);//以i下标的数为结尾的子序列的长度
    
    for(int i=1;i<n;i++){
        int mx=0;
        for(int j=0;j<i;j++){
            //每一个元素的dp值==在它之前的,比它小的元素中最大的dp值加一
            if(arr[i]>arr[j])
                mx=max(mx,dp[j]);
        }
        dp[i]=mx+1;
    }
    int res=1;
    for(int i=0;i<n;i++)
        res=max(res,dp[i]);
    cout<<res;
    return 0;
}

时间复杂度:O(n^2),空间复杂度:O(n)

全部评论
求dp的时候就可以算res的max,少一次for循环
2 回复 分享
发布于 2022-07-02 12:08

相关推荐

服从性笔试吗,发这么多笔,现在还在发。
蟑螂恶霸zZ:傻 x 公司,发两次笔试,两次部门匹配挂,
投递金山WPS等公司10个岗位 >
点赞 评论 收藏
分享
10-09 09:39
门头沟学院 C++
HHHHaos:这也太虚了,工资就一半是真的
点赞 评论 收藏
分享
6 1 评论
分享
牛客网
牛客企业服务