您的位置:首页 > 其它

最长上升子序列

2016-10-07 00:43 141 查看
最长不下降子序列:

普通的动态规划就是以f[i]表示第I个作为序列尾数的最长序列长度。然后确定状态转移方程,如果前I-1个有小于第I个数的数a[j],找出其中最大的那个数,然后f[I]=f[j]+1,否则

f[i]=1。这样由于序列是无序的,时间复杂度为O(n*2).

优化就是建一个数组A,使得A[len]=a[j],表示长度为len的上升子序列的最小末尾数。由于A[]是有序的,那么在查找的时候可以二分,总时间复杂度就是O(nlgn).

代码如下:

#include<stdio.h>
int a[1000],A[1000];
int search(int r,int target){
int l,mid;
l=0;
while(l<r){
mid=(l+r)/2;
if(A[mid]<target)
l=mid+1;
else
r=mid;
}
return l;
}
int main(){
int N,i,ans;
scanf("%d",&N);
for(i=0;i<N;i++)
scanf("%d",&a[i]);
ans=1;
A[1]=a[0];
for(i=1;i<N;i++){
if(A[ans]<a[i])
A[++ans]=a[i];
else
A[search(ans,a[i])]=a[i];
}
printf("%d\n",ans);
return 0;
}


同类问题:

1.给n条线段的左右短点坐标值,求最多多少条线段是覆盖的(Ural 1078)

2.要邀请n个人参加party,每个人有力量值strength Si和魅力值 beauty Bi,如果存在两人S i ≤ Sj and B
i ≥ Bj 或者  S
i ≥ Sj and B
i ≤ Bj
他们两个会产生冲突,问在不产生冲突的条件下,最多能邀请到几个人?

这个题有两个关键字,要保证(Si<Sj&&Bi<Bj)先按Si升序保证Si不同的人是严格上升的,然后Si相同按Bi降序,保证相同Si的人冲突(即如果Bi上升必定属于不同的Si),此时转换为了求S的最长上升子序列的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划