您的位置:首页 > 其它

【转载】动态规划--最长上升子序列(LIS)

2016-08-01 19:00 267 查看
最长上升子序列只是其中一个类型,还有最长不上升子序列、最长下降子序列、最长不下降子序列,一共四种,但是它们都是一样的。LIS全称Longest increasing subsequence,是动态规划的一种,时间复杂度为O(n^2),其实它可以优化成O(n log n)的,但是。。。具体方法我还没学到。(有空再补充吧)O(∩_∩)O

题目原型:
        给出一个长度为n数列,找出这个数列中最长上升子序列中所包含的个数。
解题思路:
  DP问题解题的一般方法就是自下而上,即先求解小的问题,然后再根据小的问题来解决大的问题,最后得到解。
那么我们首先用a数组(从0下标开始)存储要求的数列,用f[i]数组来记录以i为结尾的子序列里面包含的最长上升子序列的数字个数。那么f[i]可以接上前面任何一个比自己小的数,所以就可以求出DP方程: f[i] = max{f[j] + 1,f[i]}   其中j < i && a[j] < a[i]

参考程序:
# include <iostream>
using namespace std;
const int maxN=1000+5;
int n,a[maxN],f[maxN];
int main()
{
 cin>>n;
 for (int i=0; i<n; i++) cin>>a[i];
 int ans=0; // 初始化
 for (int i=0; i<n; i++)
 {
  f[i]=1; // 因为每个数都可以作为单独的一个序列
  for (int j=0; j<i; j++)
      if (a[j]<a[i]) f[i]=max(f[i],f[j]+1); // DP方程
  ans=max(ans,f[i]); // 求最大值
 }
 cout<<ans<<endl; // 注意不是输出f
,因为最长上升子序列的结尾不一定是最后一个
 return 0;
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: