最长递增子序列问题

设有n个数,求这个数组中最长的递增子序列。 子序列不必在原数组中是连续的。

即有:A0,A1,A2 ... An-1,求出序列: Aj1,Aj2,...Aik  该序列递增,并且其中: j1 < j2 < .. <jk, 求出最大的k。


例如对于数组: 2,3,11,6,8,4,7,12,1,9

最长递增子序列是: 2 3 4 6 8 12


求解方法如下:


设F(i)表示以A[i]结尾的最长递增子序列的长度,这里F(n)不是我们要求解的最终答案。但是如果所有的F(i),  0 <= i  < n 都求出来,该数组中最大的即是我们所求。

F(i) 与 F(i-1)有什么关系吗?

很容易得到: 由于F[i]表示以A[i]结尾的所有序列中最大的一个,如果A[i] > A[j], 说明A[i]可以追加到序列F[j]之后,否则不能追加,F[i] 是A[i]能够追加的所有这些子序列中最大的一个。递推关系如下:

F(i) = max (F(j) + 1, 如果A[i] > A[j], 并且F(i) < F(j)  )  0 <= j < i 。


如要输出求到的序列,需要保存每个以A[i]结尾构成的序列,代码如下:


#include<stdio.h>
#define MAX (256)
int main()
{    
     int i,j,n,k;
     int mpos = 0;
     int mval = 0;
     int f[MAX];
     int a[] = {2,3,11,6,8,4,7,12,1,9};
     n = 10;
     
     int res[MAX][MAX] = {0};
     
     for(i=0;i<n;i++) {
        f[i]=1;
        res[i][i] = a[i];
     }
                                                                         
    for(i=1;i<n;i++){
        for(j=0;j<i;j++){
           if(a[j]<a[i] && f[j]+1 > f[i]) {
                  f[i]= f[j]+1;   

                 // i的序列在j之上
                  for(k = 0; k <= j; ++k) 
                      res[i][k] = res[j][k];       
           }
         }        
     }


     mval = f[0];        
     for(i = 1; i < n; ++i) {
            if(f[i] > mval ) {
               mval = f[i];
               mpos = i;
            }
     }


  printf("max value = %d, pos = %d\n",mval,mpos);
  for(i = 0; i < n; ++i) {
        if(res[mpos][i] != 0)
           printf(" %d ",res[mpos][i]);      
  }  
  printf("\n");

      
return 0;


    



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值