动态规划求最大子序列和

本文介绍了一种使用动态规划求解最大子序列和问题的方法,通过遍历数组并维护一个当前子序列和来找到所有可能子序列中的最大值。算法时间复杂度为O(n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

有一串数字(可正可负的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 <0return;
    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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值