HDU-1950 Bridging signals【最長上升子序列+二分+STL】
阿新 • • 發佈:2018-11-19
題目:一個晶片左右各有n個結點,p[i]表示左邊第i個點與右邊第p[i]個點相連。求能取到的互不交叉的點的個數。
題解:本質就是求最長上升子序列,二分做法。對於一個上升子序列,顯然其結尾元素越小,越有利於在後面接其他的元素,也就越可能變得更長。
AC程式碼:
//最長上升子序列 #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <queue> #include <stack> #include <vector> #include <map> #include <set> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define inf 0x3f3f3f typedef long long ll; const int mod=1e9+7; const int maxn=1e5+7; int t,n; int p[maxn],dp[maxn]; int main() { io; cin>>t; while(t--) { cin>>n; for(int i=1;i<=n;i++) cin>>p[i]; memset(dp,inf,sizeof(dp)); dp[1]=p[1]; int ans=1; for(int i=2;i<=n;i++) { if(p[i]>=dp[ans]) dp[++ans]=p[i]; else { int j=lower_bound(dp+1,dp+1+ans,p[i])-dp; dp[j]=p[i]; } } cout<<ans<<endl; } return 0; }