各位dalao~ ~~有锅莫喷orz..... 贴AC代码
#include<iostream>
#include<cstdio>
using namespace std;
int n=0;//n是用来计数总的个数
int a[100050];
int low[100050];
int d=0;//d是长度
int find(int x)
{
int l=1,r=d,mid;
while(l<r)
{
mid=(l+r)/2;
if(x<=low[mid])
{
l=mid+1;
}
else
{
r=mid;
}
}
/*现在的数列如果要插入12;
现在的栈中的剩余元素是 28 19 15 14 13 11 9 6 4 2 1*//*low[mid]=low[5]=13*/
/*l=6*/
/*循环完了以后,l=6=r这时候就不会在进入while的这个函数,mid这时候仍然为上一步的mid,需要最后更新一次*/
mid=(l+r)/2;
low[mid]=x;
}
int find2(int x)
{
int l=1,r=d,mid;
while(l<r)
{
mid=(l+r)/2;
if(x>low[mid])
{
l=mid+1;
}
else
{
r=mid;
}
}
mid=(l+r)/2;
low[mid]=x;
}
/*389 207 155 300 299 170 158 65*/
int main()
{
while(cin>>a[++n]);
n--;//栈中的序列和实际的a序列是完全不相同的两个,必须要分开记录
for(int i=1;i<=n;i++)
{
/*开始的时候不去给low定义初值,如果不写d==0的特判就会输出d=0,不会进入函数直接输出定义的值*/
if(d==0||a[i]<=low[d])//注意要区分上升序列和不下降序列的等号差别
{
d++;
low[d]=a[i];
}
else
{
find(a[i]);
}
}
cout<<d<<endl;//an已经成功了一半lie
/*已经输出了维护好栈以后的栈的长度*/
d=0;
/*这一问其实实际就是要求去一个最长上升(严格的上升,不带等号,带等号一台设备就可以搞定了)子序列的长度orz*/
for(int i=1;i<=n;i++)
{
if(d==0||a[i]>low[d])
{
d++;
low[d]=a[i];
}
else
{
find2(a[i]);
}
}
cout<<d<<endl;
}
菜鸡lue·~~~