最长上升子序列,思路是网上搜的。。真的好巧妙,贴一下:
贪心+二分查找:(O(nlogn))
开辟一个栈,每次取栈顶元素s和读到的元素a做比较,如果a>s, 则加入栈;如果a<s,则二分查找栈中的比a大的第1个数,并替换。 最后序列长度为栈的长度。
这也是很好理解的,对x和y,如果x<y且E[y]<E[x],用E[x]替换 E[y],此时的最长序列长度没有改变但序列Q的''潜力''增大。
举例:原序列为1,5,8,3,6,7
栈为1,5,8,此时读到3,则用3替换5,得到栈中元素为1,3,8, 再读6,用6替换8,得到1,3,6,再读7,得到最终栈为1,3,6,7 ,最长递增子序列为长度4。
#include<stdio.h>
int main()
{
int t, n, c = 0, a[1000];
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
int i, total = 1;
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 1; i < n; i++)
{
if (a[i] > a[total - 1])
a[total++] = a[i];
else
{
int index = 0;
while (a[index] < a[i])
index++;
a[index] = a[i];
}
}
if (c++)
putchar('\n');
printf("%d\n", total);
}
return 0;
}