题目大意:
有n根木棍,每个木棍都有length和weight。现在有个机器要处理这些木棍,但是需要处理时间,规则如下:
a)第一根木棍需要1分钟
b)当处理完一根长度为l,宽度为w的木棍后,如果下一根木棍的长度l’和w’同时满足l’< l 且w’< w,则不需要处理时间,否则需要一分钟。
我们的目的是通过排序,最小化这个处理时间.
解题思路:
这道题是最长不下降子序列的变形题。我们先优先按照l,其次按照w排序。用一个MUQ数组记录每个最长不下降子序列的最大值。然后遍历数组,当遇到Stick[i].w< MUQ[tail]时,说明这是一个新的最长不下降子序列,我们把Stick[i].w更新到MUQ[tail]中,当Stick[i].w>=MUQ[tail],说明当前最长不下降子序列还没结束,我们就要找到Stick[i]所在的最长不下降子序列,然后把Stick[i].w更新到MUQ[tail]中。最后tail+1就是结果。
代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int l,w;
}stick;
int BS( int h, int key, int *MUQ )
{
int l = 0,m;
while ( l < h ) {
m = (l+h)/2;
if ( key >= MUQ[ m ] )
h = m;
else l = m+1;
}
return h;
}
int cmp( const void* a, const void* b )
{
stick *p = (stick *)a;
stick *q = (stick *)b;
if ( p->l == q->l )
return p->w - q->w;
return p->l - q->l;
}
int main()
{
stick Stick[ 5001 ];
int MUQ[ 5001 ];
int t,n,i,tail,j;
while ( scanf("%d",&t) != EOF )
while ( t -- ) {
scanf("%d",&n);
for ( i = 1 ; i <= n ; ++ i )
scanf("%d%d",&Stick[ i ].l,&Stick[ i ].w);
qsort( &Stick[ 1 ], n, sizeof( stick ), cmp );
tail = 0;
MUQ[ 0 ] = Stick[ 1 ].w;
for ( i = 2 ; i <= n ; ++ i )
if ( Stick[ i ].w < MUQ[ tail ] )
MUQ[ ++ tail ] = Stick[ i ].w;
else MUQ[ BS( tail, Stick[ i ].w, MUQ ) ] = Stick[ i ].w;
printf("%d\n",tail+1);
}
return 0;
}