最大子列和问题(dp解题)

给定K个整数组成的序列{ N1​, N2​, ..., NK​ },“连续子列”被定义为{ Ni​, Ni+1​, ..., Nj​ },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

输入格式:

输入第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。

输出格式:

在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。

输入样例:

6
-2 11 -4 13 -5 -2

输出样例:

20

 参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long element;

struct Kdate
{
    int element[100000];//因为是顺序表系列里的题,就建了个静态顺序表
    long size=0;         //其实普通数组就行
};

int Max(int a,int b)   //一个求最大值的函数
{
    return a>b?a:b;
}

bool Init(Kdate *p,long k)  //给定初始数组
{
    bool flag=false;        //标记特殊情况 即全为负数
    p->size=k;
    for(long i=0;i<p->size;i++)
    {
        cin>>p->element[i];
        if(p->element[i]>=0)
            flag=true;    //只要出现一个非负数,即标记为true
    }
    return flag;
}
int MaxValue(Kdate *p,long k)  //动态分布的思想
{
    int dp[100000];
    int MaxValue=p->element[0];
    dp[0]=p->element[0];        //初始状态
    for(long i=1;i<k;i++)
    {
        dp[i]=Max(p->element[i],dp[i-1]+p->element[i]);//解释见代码下方
        MaxValue=Max(dp[i],MaxValue);
    }
    return MaxValue;
}
int main()
{
    Kdate a;
    long K;
    cin>>K;
    bool f=Init(&a,K);
    if(flag)
        cout<<MaxValue(&a)<<endl;
    else
        cout<<"0"<<endl;
    return 0;
}

以第 i 个整数结尾的子数组(element [ i ])分为两种情况:

1.和第 i - 1 个整数结尾的子数组相连

2. 不相连(即单独以第 i 个的整数作为子数组)

可以得出:dp[ i ]=Max(p->element[ i ] (情况2),dp[ i-1 ]+p->element[ i ] (情况1));
MaxValue为所有 i 结尾的数组中的最大值  MaxValue=Max(dp[ i ],MaxValue);

element [ i ]    -2    11    -4    13   -5    -2
   dp[ i ]    -2    11     7    20   15    13
 MaxValue    -2    11    11    20   20     20

表格中的MaxValue为每次执行 MaxValue=Max(dp[ i ],MaxValue);后的取值


注意:

每次循环dp[ i ]的得出是:  单独以第 i 个的整数作为子数组将第 i 的整数+已有的子数组和  两者中的最大值(子数组是连续的)

MaxValue则保留dp里所有情况中的最大值

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值