最长上升子序列 和 最长不下降子序列

最长上升子序列:是严格上升的,a<b<c<d这样的,即为严格单调递增,用lower_bound

lower_bound:返回序列中大于等于key值的第一个数

比如说序列 1 2 3 4 5,key值为3,使用lower_bound返回第三个数

 

最长不下降子序列:不是严格上升,可以存在多个数相等的情况,用upper_bound

upper_bound:返回序列中严格大于key值的第一个数

比如说序列1 2 3 4 5,key值为3,使用upper_bound返回第四个数

 

Hdu 1950 求最长上升子序列

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath> 

 5 #include<stack>

 6 #include<vector>

 7 #include<map> 

 8 #include<set>

 9 #include<queue> 

10 #include<algorithm>  

11 using namespace std;

12 

13 typedef long long LL;

14 const int INF = (1<<30)-1;

15 const int mod=1000000007;

16 const int maxn=1000005;

17 

18 int a[maxn],f[maxn];

19 int n;

20 

21 int main(){

22     int T;

23     scanf("%d",&T);

24     while(T--){

25         scanf("%d",&n);

26         for(int i=1;i<=n;i++) scanf("%d",&a[i]);

27         

28         int len=1;

29         f[1]=a[1];

30         for(int i=2;i<=n;i++){

31             if(a[i]>f[len]) f[++len]=a[i];

32             else{

33                 int pos=lower_bound(f+1,f+len+1,a[i])-f;//lower_bound返回序列中大于等于key值的第一个数 

34                 f[pos]=a[i];

35             }

36         }

37         printf("%d\n",len);

38     }

39     return 0;

40 }
View Code

 

 

 

Hdu 5256

题意:给出一个数列,a1,a2,a3,a4,---,an,现在需要修改尽量少的元素,使得这个序列严格递增

因为:   a[i]<a[i+1]

又因为   a[i],a[i+1]都是整数

所以     a[i+1]-1>=a[i]

变形得   a[i+1]-(i+1)>=a[i]-i

令       b[i]=a[i]+1

所以可以求出b[i]的最长不下降子序列,再用n-len即为需要改变的最少的个数

学习的这一篇:http://blog.csdn.net/greatwjj/article/details/14518345

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath> 

 5 #include<stack>

 6 #include<vector>

 7 #include<map> 

 8 #include<set>

 9 #include<queue> 

10 #include<algorithm>  

11 using namespace std;

12 

13 typedef long long LL;

14 const int INF = (1<<30)-1;

15 const int mod=1000000007;

16 const int maxn=1000005;

17 

18 int a[maxn],f[maxn];

19 

20 int main(){

21     int T;

22     scanf("%d",&T);

23     int kase=0;

24     while(T--){

25         int n;

26         scanf("%d",&n);

27         for(int i=1;i<=n;i++) {

28             scanf("%d",&a[i]);

29             a[i]=a[i]-i;

30         }

31         

32         int len=1;

33         f[1]=a[1];

34         for(int i=2;i<=n;i++){

35             if(a[i]>=f[len]) f[++len]=a[i];//这里也和求最长上升子序列不同,是大于等于 

36             else{

37                 int pos=upper_bound(f+1,f+len+1,a[i])-f;//upper_bound返回的是序列中严格大于key值的第一个数 

38                 f[pos]=a[i];

39             }

40         }

41         printf("Case #%d:\n",++kase);

42         printf("%d\n",n-len);        

43     }

44     return 0;

45 }
View Code

 

你可能感兴趣的:(序列)