模板:
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN=500010;
int a[MAXN],b[MAXN];//a数组为原数组,b数组为存放最长上升子序列的数组
int search(int num,int low,int high) //利用二分查找的方法找到一个位置,把num插入
{
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(num>=b[mid]) low=mid+1;
else high=mid-1;
}
return low;
}
int DP(int n)
{
int i,len,pos;
b[1]=a[1];
len=1;
for(int i=2;i<=n;i++)
{
if(a[i]>=b[len])//若a[i]比b[]数组中的最大的还要大,则将其直接插入末尾
{
len=len+1;
b[len]=a[i];
}
else
{
pos=search(a[i],1,len);//关键:用二分的方法在b[]数组中找到第一个比a[i]大的位置并且让a[i]代替这个位置
b[pos]=a[i];
}
}
return len;
}
int main()
{
int n;
int lenb;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
lenb=DP(n);
printf("最长上升子序列长度为: %d\n",lenb);
for(int i=1;i<=lenb;i++)
{
printf("%d ",b[i]);
}
printf("\n");
}
return 0;
}
2015-11-26 21:00