zoukankan      html  css  js  c++  java
  • 最长上升子序列LIS

    题目:
    给你一个长度为n的序列,让你找到最长上升子序列的长度.

    分析:

    这个是dp的经典问题,今天拿来重新学习一下。

    如果按照贪心的想法,是很容易看到有问题的,比如一串数字 1,3,-3,-2,-1;

    贪心的话从1开始,依次序列结尾的数字大的数,1,3长度为2,实际上LIS的长度为3

    所以不能够用贪心来做,考虑dp。

    dp的话,首先应该拆分问题:

    要求n个,那么就找n-1个数的,n-2个数字的,找到这些状态之间的联系。

    (其实对我来说这样来思考的话,我比较难找到状态方程)

    不如从1个数字开始,假设dp[i]为当前数字结尾的序列的lis长度,那么对于前面以a[j]结尾的序列,如果a[i]>a[j],dp[i]=max(dp[j]+1);

    这样就找到了转移关系,到这里之后应该注意到,我们只是把每一个数字结尾的lis找了出来,但这不是全局最优解,所以应该再找到最大的dp[i],才是最后的结果。

    代码如下:

    #include<iostream>
    using namespace std;
    int a[100001];
    int dp[100001];
    int main()
    {
    int i,j,n;
    int ans=0;
    cin>>n;
    for(i=0;i<n;i++)
    {
    cin>>a[i];
    dp[i]=1;
    }
    for(i=1;i<n;i++)
    {
    for(j=0;j<i;j++)
    {
    if(a[j]<a[i])
    {
    dp[i]=max(dp[i],dp[j]+1);
    }
    }
    ans=max(ans,dp[i]);//一边计算dp[i]一边求出了最大dp[i]
    }
    cout<<ans<<endl;

    return 0;
    }

    对于求最优解问题来说,先看下能不能贪心,不能,用dp.

    对于dp问题,最重要的是拆分问题,问题怎么拆?我们假设什么量来表示,这个应该是解决问题的关键吧。

  • 相关阅读:
    解决跨域问题 cors~ JSONP~
    session,cookie,sessionStorage,localStorage的区别~~~前端面试
    数据库索引的理解
    script的按需加载
    es6 笔记
    JS 工具函数
    JS Error
    数组方法重写:forEach, map, filter, every, some, reduce
    JS: GO 和 AO
    立即执行函数
  • 原文地址:https://www.cnblogs.com/renxin123/p/8436514.html
Copyright © 2011-2022 走看看