给定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里所有情况中的最大值