_xiaobai_

导航

zoj1025 Wooden Sticks(DP)

/*
 问题:求解一个序列中的不上升序列的最小个数:
 定理:一个序列中的不上升序列的最小个数,是他的最大上升自序列长度。
 补充:利用单调队列可以是O(N^2)的算法,优化成O(NlogN)
 */

View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3
4 typedef struct node
5 {
6 int l,w;
7 }stick;
8
9 int BS( int h, int key, int *MUQ )
10 {
11 int l = 0,m;
12 while ( l < h ) {
13 m = (l+h)/2;
14 if ( key >= MUQ[ m ] )
15 h = m;
16 else l = m+1;
17 }
18 return h;
19 }
20
21 int cmp( const void* a, const void* b )
22 {
23 stick *p = (stick *)a;
24 stick *q = (stick *)b;
25 if ( p->l == q->l )
26 return p->w - q->w;
27 return p->l - q->l;
28 }
29
30 int main()
31 {
32 stick Stick[ 5001 ];
33 int MUQ[ 5001 ];
34
35 int t,n,i,tail,j;
36 while ( scanf("%d",&t) != EOF )
37 while ( t -- ) {
38 scanf("%d",&n);
39 for ( i = 1 ; i <= n ; ++ i )
40 scanf("%d%d",&Stick[ i ].l,&Stick[ i ].w);
41
42 qsort( &Stick[ 1 ], n, sizeof( stick ), cmp );
43 tail = 0;
44 MUQ[ 0 ] = Stick[ 1 ].w;
45
46 for ( i = 2 ; i <= n ; ++ i )
47 if ( Stick[ i ].w < MUQ[ tail ] )
48 MUQ[ ++ tail ] = Stick[ i ].w;
49 else MUQ[ BS( tail, Stick[ i ].w, MUQ ) ] = Stick[ i ].w;
50
51 printf("%d\n",tail+1);
52 }
53 return 0;
54 }

posted on 2011-08-17 13:22  _xiaobai_  阅读(270)  评论(0编辑  收藏  举报