Question: calculate the maximum number of subsequences that do not increase in a sequence.
Analysis: DP, Lis. The minimum number of non-ascending subsequences in a sequence is its maximum ascending subsequence length.
Proof: First, find the Maximum ascending sub-sequence of the string, then each element must belong to a different non-descending string;
If the first largest ascending subsequence is used, each element must be the maximum value in the set;
The maximum values can be used to determine a substring instead of a substring, which corresponds to a set. Therefore, the lower bound is | Lis |;
Assume that a set P exists. The maximum value p is not in LIS and does not belong to the preceding set;
He determines a sequence without going up, and sets the maximum value of the set before him to Lis (I );
Then there is Lis (I)> = P (otherwise P is Lis (I + 1); replace Lis (I) with P in the collection,
For a part smaller than P, we obtain the set determined by the new Lis (I) and a new independent set P1;
If you set the maximum P1 value to P1, there are two possibilities:
1. Lis (I-1) <P1 <Lis (I) can constitute a longer Lis, then the result is still | Lis |, prove;
2. Lis (I-1)> = p1 repeat the above operation and keep getting the PJ set until 1 is set up or I = 1;
If I is 1, pj <Lis (1) goes to the top of the longer Lis; otherwise, 1 is true.
Note: The monotonous queue can be an O (N ^ 2) algorithm and optimized to O (nlogn ). )
#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;}
Zoj 1025-wooden sticks