最长合法序列
Time Limit:1000MS Memory Limit:65536K
Total Submit:55 Accepted:4
Description
有k个整数A[1],A[2]…A[k](0 < a[i] <= 2000000000, 0 < i <= k, 0 < k <= 1000,),你需要从前往后选出若干数,
使得每一个后面的数都要大于或等于前面的数。例如,对于序列1,4,2,5,2,3,选出1,2,2,3是合法的,但是选出4,2,3是不合法的。
请你编写程序对于一个已知序列,求出最长的合法序列的数的个数。
Input
每组测试数据由两行组成:
第一行为整数k,表示k个整数;
第二行有k个数A[1],A[2]….A[k]。
测试数据以0做为结束标志
Output
输出2*n行,先输出一个整数,表示相应测试序列中最长的合法序列的数的个数。
再输出一行表示最长合法序列是什么
Sample Input
1213 45 23 53 23 88 123 3 125 10 87 89
6
1 4 2 5 2 3
0
Sample Output
6
13 ,45 ,53 ,88 ,123 ,125
4
1 ,2 ,2 ,3
代码如下:
#include <iostream>
#include <fstream>
using namespace std;
int maxValue(int a[],int len[],int n)
{//求a数组的前n元素中<=a[n]的最长子序列的长度
int j=-1,maxlen=0;
for(int i=0;i<n;i++)
{
if(a[i]<=a[n] && len[i]>maxlen)
{
j=i;maxlen=len[i];
}
}
return j;//len[j]是最长子序列的长度
}
void ress(int a[],int path[],int i)
{//利用递归输出最长合法子序列(最长非递减子序列)
if(path[i]!=-1)
{
ress(a,path,path[i]);
cout<<" ,"<<a[i];
}
else
cout<<a[i];
}
int main(int argc, char *argv[])
{
int i;
int n;
int *a,*len,*path; //a数组存储一组测试数据的n个整数
//len[i]存储a[0]~a[i]序列中最长子序列的长度
//path[i]存储最长合法子序列中a[i]的前一个整数的位置(下标)
while(1)
{
cin>>n;
if(n==0) break;
a=new int[n];
len=new int[n];
path=new int[n];
for(i=0;i<n;i++)
{
cin>>a[i];
if(i==0) { //初始化
len[i]=1;
path[i]=-1;
}
else
{
int j=maxValue(a,len,i);
if(j==-1) {
len[i]=1;
path[i]=-1;
}
else{
len[i]=len[j]+1;
path[i]=j;
}
}
}
int maxlen=0,maxi=0;
for(int j=0;j<n;j++)
{
if(len[j]>maxlen) {
maxlen=len[j];
maxi=j;
}
}
cout<<maxlen<<endl;
ress(a,path,maxi,cout);
cout<<endl;
delete [] a;
delete [] len;
delete [] path;
}
system("PAUSE");
return 0;
}