最长上升子序列o(nlongn)写法
dp[1]=a[1]; int len=1; for(int i=1;i<=n;i++){ if(a[i]>dp[len]) dp[++len]=a[i]; else *lower_bound(dp+1,dp+1+len,a[i])=a[i]; }
数组dp[len]描述的是长度为len时的结尾的最小元素。
怎么样才能不交叉呢?i和j相连,i1和j1想连,只有i<i1&&j<j1时才不会交叉,所以让第行单调递增,然后第而行求他的LIS
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5E5+7; const int INF=1E9+7; struct stu{ int a,b; bool friend operator <(const stu x,const stu y){ return x.a<y.a; } }arr[N]; int a[N],dp[N]; int main(){ ios::sync_with_stdio(0); int n; int t=0; while(cin>>n){ for(int i=1;i<=n;i++) cin>>arr[i].a>>arr[i].b; sort(arr+1,arr+1+n); for(int i=1;i<=n;i++){ a[i]=arr[i].b; } dp[1]=a[1]; int len=1; for(int i=1;i<=n;i++){ if(a[i]>dp[len]) dp[++len]=a[i]; else *lower_bound(dp+1,dp+1+len,a[i])=a[i]; } cout << "Case " << ++t << ":\n"; cout << "My king, at most " << len << (len > 1 ? " roads" : " road") << " can be built.\n\n"; } return 0; }
注:sb了。为什么要用struct呢?还得排序,,,直接a[x]=y就行.....