您的位置:首页 > 产品设计 > UI/UE

njust 1925 sequence 拆分序列,寻找非降序列的最小个数,不变序列顺序。

2016-05-05 20:33 435 查看
     
维护一个数组,保存多个非递减序列的最后一个值。 
显然,这个数组一定是递减的。 
例如上面样例中的 7 6 9 8 10 
初始时,我们令a[0] = 7,表示目前有一个序列,最后一个值为7 
接下来到6了,因为6小于7,所以只能使用一个新的序列,令a[1] = 6 
到9,我们发现9既可以放在7后面,也可以放在6后面,那我们当然选择在7后面放,相比放在6后面会更好。 
也就是说,假如当前需要放入x,那就在数组中找小于等于x的最大值,更新它为x。 
因为数组是递减的,所以寻找的这个过程可以使用二分查找。       


Description

将一个给定的数列,拆分成K个不降序列,每个数出现且只出现一次,且在各序列中各个数相对于原数列的相对顺序不变。如7 6 9 8 10可以拆成 7 9 10和6 8。求最小的K值。


Input

第一行输入一个整数T(1 <= T <= 100),表示接下来T组测试数据,每组两行,第一行为n,代表数列长度(1<=n<=10000)接下来一行有n个数,空格分隔(每个数<=50000)。


Output

对每组数据输出一个最小的K值。


Sample Input

2
5
7 6 9 8 10
5
5 4 3 2 1



Sample Output

2
5


#include<stdio.h>
int d[50020];
int find(int s,int l,int x)
{
while(s<=l)
{
int mid=(s+l)/2;
if(x<d[mid])
s=mid+1;
else if(x>d[mid])//二分过程寻找每个非降序序列的最后一个数存到固定数组里。
l=mid-1;
else
return mid;
}
return s;
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int m;
scanf("%d",&m);
int z=0;
d[z]=0;
for(int i=0; i<m; i++)
{
int p;
scanf("%d",&p);
int len=find(0,z,p);
//printf("%d@\n",len);
if(len>z)
d[++z]=p;//存到数组里,并记录长度。
else
d[len]=p;
}
printf("%d\n",z+1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: