动态规划法-----最长增序子序列(非连续)

动态规划法-----最长增序子序列(非连续)

           动态规划法 求最长非连续增序子序列

    问题描述

  一个整形数组a[]= {1 ,7, 3, 5, 9, 4, 8},其中a0 ,a1为一个递增子序列长度为2, a0 a2 a5 a6为一个递增序列,其长度为4,且为最长的递增子序列。

   解决方案

   设b[j]为以a[j]结束的最长递增序列的长度,则b[j] = max(b[k]) ,其中1<=k<j ,且a[k] < a[j] 。 问题的答案为max(b[j]) 1<= j <= n 。

   解决方法类似求最大连续子序列和的问题。
  


  代码如下

  
/**/ /*
  定义s[i] 表示第i个位置处,以a[i]为结尾的最大递增长度 
  先求每个位置处的最大长度,然后遍历求最大长度即可 
  下面一步增加一个存储结构,存储究竟是哪几个数组构成了递增的最大长度的数组 
*/


#include 
< iostream >
 
using   namespace  std ;
 
const   int  N  =   1010  ;
 
 
int  s[N] ;
 
int  a[N]  ; 
 
int  p[N]  ;  // p[i] 表示 以a[i]结尾的最长子串的前一个节点的标号 
  int  main()
 
{
   
int n , i , k;
   scanf(
"%d" , &n) ;
   
for(i = 0 ; i < n ;i++)
   
{
     scanf(
"%d" ,&a[i]);
     s[i] 
= 1 ;
     p[i] 
= i ; //初始化每一个路径   
   }

   
   
for(i = 0 ; i < n ; i++)  
    
{
      
for(k = 0 ; k < i ; k++)
       
{
         
if(a[i] > a[k])
         
{
            
int q = s[k] + 1 ;  
            
if(s[i] < q) 
             
{
               s[i] 
= q ;
               p[i] 
= k ;       
             }

         }
             
       }
         
    }
 
   
   
int max = 0 ;  
   
for(i = 0 ; i < n ;i++)  
   
{
    
       
if(s[max] < s[i])  
          max 
= i ;     
   }

     printf(
"%d\n" , s[max]) ;

 
   
while(1)
   
{
    printf(
"%d->" , a[max]) ;      
    
if(max == 0)
     
break ;
    max 
= p[max] ;    
   }

   
     system(
"pause");
    
return 0 ;   
 }
 

你可能感兴趣的:(动态规划法-----最长增序子序列(非连续))