您的位置:首页 > 其它

动态规划——最长递增子序列

2017-04-03 16:36 211 查看
问题描述:

对于一个数字序列,请设计一个复杂度为O(nlogn)的算法,返回该序列的最长上升子序列的长度,这里的子序列定义为这样一个序列U1,U2...,其中Ui < Ui+1,且A[Ui] < A[Ui+1]。

给定一个数字序列A及序列的长度n,请返回最长上升子序列的长度。




测试样例:

[2,1,4,3,1,5,6],7

返回:4




解法:

将该问题划分为子问题,长度为1、2、3……n的子序列进行求解,

假设A[i]为数字序列中的第i个数,MAX[i]为长度为i时最长上升子序列的长度,则

MAX[1]=1;

MAX[i]=MAX[j]+1; (必须满足:
A[i]>A[j] && j<i &&
MAX[j]为0到i-1区间内最大的)


具体代码如下:

#include <iostream>
#include <vector>
using namespace std;
int findLongest(vector<int> a, int n)
{
vector<int> max(n, 1); //记录长度为n时的最长上升子序列
int maxlen = 1; //记录全局最长,最少为1

for (int i = 1; i < n; i++) //i为长度,分别求解长度为i时候的,这里从1开始因为数组的下标是0开始的,而只有一个数的时候必然最长为1,所以直接从第二个数开始
{
int maxtmp = 0;
for (int j = 0; j < i; j++) //找到比a[i]小的数,并且寻找其中上升子序列最长的
{
if (a[i] > a[j] && max[j]>maxtmp)
maxtmp = max[j];
}
max[i] = maxtmp + 1;
if (max[i] > maxlen) maxlen = max[i]; //记录当前长度最长
}
return maxlen;
}
int main()
{
//测试用例
vector<int> v{ 2,1,4,3,1,5,6 };
int n = 7;
cout << findLongest(v, n) << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息