hdu 5532 (最长上升子序列)nlogn

来源:互联网 发布:西安聚航网络 编辑:程序博客网 时间:2024/05/19 23:16

通过这一次,彻底的理解了最长上升子序列

一开始我套程序设计竞赛的模板,就是不对

又看了kuangbin的,别人博客的,最后真正理解了,花了3,4个小时,自己好菜啊

不同的人有不同的写法

分为上升,不递减两种

程序设计竞赛的

第一种

int solve(int a[]){for(int i=0;i<n;i++)dp[i]=INF;for(int i=0;i<n;i++)*lower_bound(dp,dp+n,a[i])=a[i];return lower_bound(dp,dp+n,INF)-dp;}
第二种

int solve(int a[]){for(int i=0;i<n;i++)dp[i]=INF;for(int i=0;i<n;i++)*upper_bound(dp,dp+n,a[i])=a[i];return lower_bound(dp,dp+n,INF)-dp;}
kuangbin的

int search(int num,int low,int high){int mid;while(low<=high){mid=(low+high)/2;if(num>=dp[mid]) low=mid+1;else high=mid-1;}return low;}int solve(int a[]){int len,pos;dp[1]=a[1];len=1;for(int i=2;i<=n;i++){if(a[i]>dp[len]){   //如果a[i]比dp最后一位大,就插入,这保证了是递增序列 len++; dp[len]=a[i];}else {pos=search(a[i],1,len);dp[pos]=a[i];}}return len;}

第二种 换成>=

别人博客的

int LIS(int a[], int n) {    int len = 1; b[0] = a[0];    for (int i = 1; i < n; i++) {      b[a[i] > b[len - 1] ? len++ : lower_bound(b, b + len, a[i]) - b] = a[i]; //非降换为>=和upper_bound    }    return len;
ac代码

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;int n,len;int dp[100005];int a[100005],b[100005];int solve(int a[]){int len;dp[0]=a[0];len=1;for(int i=1;i<n;i++){dp[a[i] >= dp[len - 1] ? len++ : upper_bound(dp, dp+ len, a[i]) - dp] = a[i];}return len;}int main(){int t;scanf("%d",&t);while(t--){scanf("%d",&n);int flag=n-1;for(int i=0;i<n;i++){scanf("%d",&a[i]);b[flag--]=a[i];}int sum1=solve(a),sum2=solve(b);if((sum1>=n-1)||(sum2>=n-1)) printf("YES\n");else printf("NO\n");} } 







原创粉丝点击