1. 程式人生 > >poj1631 dp,最長上升子序列

poj1631 dp,最長上升子序列

題目描述:

  給你兩列點,共2n個

  對於1~n著n個數,每個數給定一個對應的數xi,表示左邊的點i與右邊的點xi相連,求問這些連線中,最大的不交叉的連線數量

  

可以觀察樣例

我們可以發現,滿足不交叉這一條件的必要條件是對於i<j,必有xi<xj,(否則,連線一定相交)

所以,我們就可以發現,這是一道最長上升子序列的問題

因為資料範圍是n<40000,所以要用nlogn的二分搜尋LIS

可解

附上程式碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4
#include<cstring> 5 using namespace std; 6 int up[50000]; 7 int down[50000]; 8 int port[50000]; 9 int n; 10 const int inf=9999999; 11 int solve1() 12 { 13 fill(up,up+n,inf); 14 for(int i=0;i<n;i++) 15 { 16 *lower_bound(up,up+n,port[i])=port[i]; 17 } 18 return lower_bound(up,up+n,inf)-(up);
19 } 20 21 int main() 22 { 23 //freopen("in.txt","r",stdin); 24 int T;cin>>T; 25 while(T--) 26 { 27 scanf("%d",&n); 28 for(int i=0;i<n;i++) {scanf("%d",&port[i]);} 29 //cout<<solve1(); 30 31 cout<<solve1()<<endl; 32 }
33 }
View Code