标签:style blog http io ar color os sp for
给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长子序列,并求出其长度。
如:1 9 10 5 11 2 13的最长单调递增子序列是1 9 10 11 13,长度为5。
7 1 9 10 5 11 2 13 2 2 -1
5 1
经典代码超时,复杂度(n*n)。
#include<stdio.h> #include<algorithm> using namespace std; int a[100010]; int dp[100010]; int main() { int i,j,n; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) { scanf("%d",&a[i]); dp[i]=1; } for(i=n-2;i>=0;i--) { for(j=i+1;j<n;j++) { if(a[i]<a[j]&&dp[i]<dp[j]+1) dp[i]=dp[j]+1; } } sort(dp,dp+n); printf("%d\n",dp[n-1]); } return 0; }二分查找,复杂度n(logn)可以飘过!
详细算法参考: 最少拦截系统(杭电1257)
#include<stdio.h> #include<string.h> int a[100010]; int s[100010]; int len,i; int search(int i) { int left=1,right=len; while(left<right) { int mid=(left+right)/2; if(s[mid]>a[i]) right=mid; else if(s[mid]==a[i]) return mid; else left=mid+1; } return left; } int main() { int j,n; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) scanf("%d",&a[i]); len=1; s[len]=a[1]; for(i=2;i<=n;i++) { if(a[i]>s[len]) { len++; s[len]=a[i]; } else { j=search(i); s[j]=a[i]; } } printf("%d\n",len); } return 0; }
标签:style blog http io ar color os sp for
原文地址:http://blog.csdn.net/hdd871532887/article/details/41761845