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

最长上升子序列:是严格上升的,a

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

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 #include

10 #include

11 using namespacestd;12

13 typedef long longLL;14 const int INF = (1<<30)-1;15 const int mod=1000000007;16 const int maxn=1000005;17

18 inta[maxn],f[maxn];19 intn;20

21 intmain(){22 intT;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],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

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 #include

10 #include

11 using namespacestd;12

13 typedef long longLL;14 const int INF = (1<<30)-1;15 const int mod=1000000007;16 const int maxn=1000005;17

18 inta[maxn],f[maxn];19

20 intmain(){21 intT;22 scanf("%d",&T);23 int kase=0;24 while(T--){25 intn;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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值