例如:整数组成的数列为3,18,7,14,10,12,23,41,16,24。则3,18,23,24就是一个长度为4的不下降序列。同时还有3,7,10,12,16,24或3,7,10,12,23,41都是长度为6的最长不下降序列。
请编写算法求出一个数列的最长不下降序列。
分析:若从a(i)开始,此时最长不下降序列应该按下列方法求出:
再a(i+1),a(i+2),…,a(n)中,找出一个起始数据比a(i)大的且最长的不下降序列,作为它的后继。
数据结构设计:
vector容器max_sub_num[i]记录点i到n的最长不下降子序列的长度,ind_nex_num[i]记录点i在最长的不下降子序列的后继数据编号。
C++代码:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> data;
vector<int> max_sub_num;
vector<int> ind_nex_num;
int tmp;
while (cin>>tmp)
{
data.push_back(tmp);
max_sub_num.push_back(1);
ind_nex_num.push_back(0);
}
int n = data.size();
if (n == 0)
{
cout<<"输入有误."<<endl;
exit(1);
}
//找出以点i为起点到n的最长不下降子序列
for(int i=n-1;i>=0;--i)
{
int maxlen = 0;
int p=0;
for (int j=i+1;j<n;++j)
{
if (data[i] < data[j] && max_sub_num[j] > maxlen)
{
maxlen = max_sub_num[j];
p = j;
}
}
if (p != 0)
{
ind_nex_num[i] = p;
max_sub_num[i] = max_sub_num[p]+1;
}
}
int maxLen = 0;
int p = 0;
for (int i=0;i<max_sub_num.size();++i)
{
if (max_sub_num[i] > maxLen)
{
p = i;
maxLen = max_sub_num[i];
}
}
cout<<"maxLong:"<<maxLen<<endl;
do
{
cout<<data[p]<<' ';
p = ind_nex_num[p];
}while(p != 0);
cout<<endl;
return 0;
}
// 3 18 7 14 10 12 23 41 16 24
运行结果: