您的位置:首页 > 其它

wust oj 1867 (输出最长不下降子序列)【最长序列输出类模板】

2017-07-26 20:28 344 查看


Description

       设有由n个不相同的整数组成的数列,记为:b(1)、b(2)、……、b(n)且b(i)<>b(j)  (i<>j),若存在i1<i2<i3< … < ie 且有b(i1)<b(i2)< … <b(ie)则称为长度为e的不下降序列。程序要求,当原数列出之后,求出最长的不下降序列。
       例如13,7,9,16,38,24,37,18,44,19,21,22,63,15。例中13,16,18,19,21,22,63就是一个长度为7的不下降序列,同时也有7 ,9,16,18,19,21,22,63长度为8的不下降序列。


Input

实现一个整数n,表示整数个数。接着包含n个整数。(不超过1000)


Output

首先输出最长不下降序列的长度,形如“max=长度”。

第二行就是最长不下降序列中的各个整数。如果有多个答案,只输出最前面的序列。


Sample Input 

  7 300 250 275 252 200 138 245

 

Sample Output

max=2

250 275

 【题解】 学到这我想求最长不下降子序列大家应该都会,但是这道题比较特别,许多人都会求其长度,但是会输出这个最长子序列的恐怕不多吧,,这里面还是有一点小技巧的。

 

 首先就是开三个数组,一个存数据,一个标记从每个数据开始到末尾的最长子序列个数,并记录路径,最后一个存它的路径,路径的保存采取并查集的形式,当然并没有用到并查集,不要惊讶,,

 你可以把它想象成指针,前一个指针指向一个元素的地址,而此元素里存的是下一个符合条件的地址,这样就可以每次输出每个地址内的元素内容,达到保存路径的目的。

 

 就像->->->->->...原理一样,希望你能理解。

 【AC代码】

 

#include <iostream>
#include <vector>
using namespace std;

int main()
{
int tmp,t;
while (cin>>t)
{
vector<int> data;//开数组
vector<int> max_sub_num;
vector<int> ind_nex_num;
while(t--)
{
cin>>tmp;
data.push_back(tmp);//读入数据
max_sub_num.push_back(1);//每个数据刚开始的最长不下降子序列都是1
ind_nex_num.push_back(0);//后继都为0
}
int n = data.size();
for(int i=n-1;i>=0;--i)//从都往前遍历
{
int maxlen = 0;
int p=0;
for (int j=i+1;j<n;++j)//记录从第i个数到最后一个数之间的最长不下降子序列
{
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;//记录从i点往后的最长不下降序列长度
max_sub_num[i] = max_sub_num[p]+1;//i点起往后的最大不下降序列长度加1
}
}
int maxLen = 0;
int p = 0;
for (int i=0;i<max_sub_num.size();++i)//遍历所有从i开头的元素,找到最长序列
{
if (max_sub_num[i] > maxLen)
{
p = i;
maxLen = max_sub_num[i];
}
}
cout<<"max="<<maxLen<<endl;//输出序列
cout<<data[p];
p= ind_nex_num[p];
while(p!=0)
{
cout<<" "<<data[p];
p = ind_nex_num[p];
}
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐