本文中只讲到了升序,降序只要将大于号换成小于号即可
本题用普通动态规划求解,递推式为:f[i]=max{f[j]+1,a[i]<a[j]},f[i]表示以a[i]结尾的最长递减子序列的长度。初始条件f[i]=1,1<=i<=n,通过枚举i,j,可求出问题的解,解为max{f[i],1<=i<=n}。复杂度O(n^2)。
#include <iostream>
#include <vector>
using namespace std;
void MaxOrderedSeqence(const vector<int> &data)
{
int num=data.size();
vector<int> array(num,1);
//以n结束的最长子序列的长度存在array[n]中
//所以array中是长度
for(int i=0;i<num;i++)
{
int max=0;
for(int j=0;j<i;j++)
{
//找到i前边的某个点,这个点比i的值小,还是比i小的所有点中array值最大的
if(data[j]<data[i] && max<array[j])
{
max=array[j];
}
}
//以i为终点的最长序列长度为这个值加一
array[i]=max+1;
}
int result=0;
int last=0;
//找到array中的最大值便是最长序列长
//last为这array中的下标,也就是最长序列的终点
for(int k=0;k<num;k++)
{
if(array[k]>result)
{
result=array[k];
last=k;
}
}
vector<int> arraySeq(result,0);
//arraySeq中存下标,一个最长序列的下标
//终点已经确定了
arraySeq[result-1]=last;
//循环填满arraySeq
for(int m=result-2;m>=0;m--)
{
//n从已确定的最前边的下边的上一个开始
for(int n=arraySeq[m+1]-1;n>=0;n--)
{
//以已确定的最前边顶点为终点最长序列的值比当以前顶点为终点的最长序列值大一
//而且这个最前边的顶点的值大于当前值顶点对应的元素值,则当前顶点为所求顶点
if(array[arraySeq[m+1]]==array[n]+1&&data[arraySeq[m+1]]>data[n])
{
arraySeq[m]=n;
break;
}
}
}
cout<<"the long of the sequence:"<<result<<endl;
cout<<"the sequence:"<<endl;
for(m=0;m<result;m++)
{
cout<<data[arraySeq[m]]<<" ";
}
cout<<endl;
}
int main()
{
cout<<"input the size of the array:"<<endl;
int num;
cin>>num;
vector<int> arr(num,0);
for(int i=0;i<num;i++)
cin>>arr[i];
MaxOrderedSeqence(arr);
return 1;
}