本题目主要求最长上升子序列,dp,n^2的算法能过,数据有点弱。下面还有用二分优化的算法。
/*//o(n^2)
#include<iostream>
#define max(a,b) a>b?a:b
using namespace std;
int main()
{
int i,j,k,l,m,mMax;
int h[33000],f[33000];
k=1;
while(k>0)
{
memset(f,0,sizeof(f));
scanf("%d",&l);
if(l==-1)
break;
else if(k!=1)
printf("/n");
h[0]=l;
m=1;
while(1)
{
scanf("%d",&h[m]);
if(h[m]==-1)
break;
m++;
}
f[0]=1;
mMax=1;
for(i=1;i<m;i++)
{
f[i]=1;//注意初值
for(j=0;j<i;j++)
{
if(h[i]<h[j])
{
f[i]=max(f[i],f[j]+1);
}
}
if(mMax<f[i])
mMax=f[i];
}
printf("Test #%d:/n",k++);
// if(mMax==1)
// printf(" maximum possible interceptions: %d/n",mMax);
// else
printf(" maximum possible interceptions: %d/n",mMax);
}
return 0;
}
*/
//o(nlogn)二分查找
/*
#include<iostream>
#include<algorithm>
#define max(a,b) a>b?a:b
using namespace std;
int h[33000],f[33000];
int len,m;
int search(int ai)
{
int l=1,r=len,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(ai<f[mid-1]&&ai>=f[mid])return mid;
else if(ai<f[mid]) l=mid+1;
else r=mid-1;
}
return -1;
}
int main()
{
int i,j,k,l,m;
k=1;
while(k>0)
{
memset(f,0,sizeof(f));
scanf("%d",&l);
if(l==-1)
break;
else if(k!=1)
printf("/n");
h[1]=l;
m=2;
while(1)
{
scanf("%d",&h[m]);
if(h[m]==-1)
break;
m++;
}
m--;
// reverse(h+1,h+m);
f[1]=h[1];len=1;
for(i=2;i<=m;i++)
{
if(h[i]>=f[1])
j=1;
else if(h[i]<f[len])
j=++len;
else
j=search(h[i]);
f[j]=h[i];
}
printf("Test #%d:/n",k++);
printf(" maximum possible interceptions: %d/n",len);
}
return 0;
}
*/ //poj1731
#include<iostream>
#include<algorithm>
using namespace std;
int h[41000],f[41000];
int len;
int search(int ai)
{
int l=1,r=len,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(f[mid]<=ai)
l=mid+1;
else
{
if(mid-1<1||f[mid-1]<=ai)
return mid;
else
r=mid-1;
}
//if(ai>f[mid-1]&&ai<=f[mid])return mid;
//else if(ai<f[mid]) l=mid+1;
//else r=mid-1;
}
return -1;
}
int main()
{
int i,j,k,m;
scanf("%d",&k);
while(k--)
{
scanf("%d",&m);
for(i=1;i<=m;i++)
scanf("%d",&h[i]);
f[1]=h[1];len=1;
for(i=2;i<=m;i++)
{
if(h[i]<f[1])
j=1;
else if(h[i]>=f[len])
j=++len;
else
j=search(h[i]);
f[j]=h[i];
}
printf("%d/n",len);
}
return 0;
}