动态规划求最大子序列和

问题描述:

有一串数字(可正可负的int,放在数组Num里),要求找到起始位置start和终止位置end,使得从start位置到end位置的所有数字之和最大,返回这个最大值max。

最简单的方法是用动态规划算法实现:
设 f[x] 为以 a[x] 终止且包含 a[x] 的最大序列的和,有:
f[1] = a[1];
f[x+1] = f[x] > 0 ? f[x] + a[x+1] : a[x+1]
那么最大子序列的和就是 f[1] .. f[n] 中最大的一个。

算法的时间复杂度为O(n),代码实现如下:


#define  MaxSize 10000 +10
int  k,max,s,e,cmax,cs,ce;
int  nums[MaxSize];

void  ready()
{
    
int  i;
    max 
=  nums[ 1 ];
    s 
=   1
    e 
=   1 ;
    
for ( i = 1 ; i <= k; i ++ )
        
if (max  <  nums[i]) 
        { 
            max 
=  nums[i];
            s 
=  i; 
            e 
=  i;
        }

}
void  compute()
{
     
//  求数组nums[]中连续子序列的最大和,并标出该子序列
    
//  设 f[x] 为以 a[x] 终止且包含 a[x] 的最大序列的和,有:
    
//     f[1] = a[1];
    
//     f[x+1] = f[x] > 0 ? f[x] + a[x+1] : a[x+1]
    
//  那么最大子序列的和就是 f[1] .. f[n] 中最大的一个
     int  i,j;
    
if ( max  < 0 return ;
    cmax 
=  nums[ 1 ];
    cs 
=   1 ;
    ce 
=   1 ;
    
for ( i = 2 ; i <= k ; i ++ )
        
if (cmax  > 0 )
        {
            cmax
+=  nums[i];
            ce 
=  i;
            
if ( cmax  >  max) 
            {
                max 
=  cmax;
                s 
=  cs;
                e 
=  ce;
            }
        }
        
else
        {
            cmax 
=  nums[i];
            cs 
=  i;
            ce 
=  i;
        }
}

 

void  MaxSubseq_DP( int  nums[],  int  count,  int   & resStart,  int   & resEnd,  int   & resMax)
{
    
// 求数组nums[]中连续子序列的最大和,并标出该子序列
    
// 设 f[x] 为以 a[x] 终止且包含 a[x] 的最大序列的和,有:
    
//    f[1] = a[1];
    
//    f[x+1] = f[x] > 0 ? f[x] + a[x+1] : a[x+1]
    
// 那么最大子序列的和就是 f[1] .. f[n] 中最大的一个
    int start, max;
    
int i;
    
    start 
= resStart = resEnd = 0//初始化当前子序列和最大子序列为nums[0]
    max = resMax = nums[0];

    
for (i = 1; i < count; ++i) {
        
if (max > 0{
            max 
+= nums[i];
        }
 else {
            max 
= nums[i]; //抛弃当前子序列
            start = i; //开始新的子序列搜索
        }

        
        
if (resMax < max) //更新最大子序列
            resMax = max;
            resStart 
= start;
            resEnd 
= i;
        }

    }
//for

    
return;
}



转载于:https://www.cnblogs.com/Steven7Gao/archive/2009/10/06/1578456.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值