5 1 5 3 2 4 5 3 4 2 1
3
最长公共子序列向最长递增子序列退化:
设有序列A,B。记序列A中各个元素在B 中的位子(降序排列),然后按在A中的位置依次列出按后求A的最长递增子序列。
例如:有A={a,b,a,c,x},B={b,a,a,b,c,a}则有a={6,3,2},b={4,1},c={5};x=/;(注意降序排列)
然后按A中次序排出{a(6,3,2),b(4,1),a(6,3,2),c(5),x()}={6,3,2,4,1,6,3,2,5};对此序列求最长递增子序列即可
#include <vector> #include <cstring> #include <memory> #include <algorithm> #include <cstdio> using namespace std; #define MAX 100001 int A[MAX], B[MAX], D[MAX]; int pos[MAX], hash[MAX]; int bfind ( int l, int r, int key ) { int mid; while ( l < r ) { mid = ( l + r ) / 2; if ( key <= D[mid] ) r = mid; else l = mid + 1; } return r; } int main() { int n; while ( scanf("%d",&n) != -1 ) { int len = 0, i; for ( i = 1; i <= n; i++ ) { scanf("%d",&A[i]); hash[A[i]] = i; } for ( i = 1; i <= n; i++ ) { scanf("%d",&B[i]); pos[i] = hash[B[i]]; } D[0] = 0; for ( i = 1; i <= n; i++ ) { if ( pos[i] > D[len] ) D[++len] = pos[i]; else { int p = bfind ( 1, len, pos[i] ); D[p] = pos[i]; } } printf("%d\n",len); } return 0; }