题目描述
给出一段序列,选出其中连续且非空的一段使得这段和最大。
输入格式
输入文件maxsum1.in的第一行是一个正整数N,表示了序列的长度。
第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列。
输入文件maxsum1.out,仅包括1个整数,为最大的子段和是多少。子段的最小长度为1。
输入输出样例
输入样例:7 2 -4 3 -1 2 -4 3
输出样例:4
【数据规模与约定】
对于40%的数据,有N ≤ 2000。
对于100%的数据,有N ≤ 200000。
- 耗时限制1000ms
- 内存限制128MB
最大子段和是指一个数组中,所有连续子段中和最大的子段的和。常见的解法有暴力、分治、动态规划等。
以下是一个基于动态规划的最大子段和算法:
-
定义状态:设 dp[i] 表示以第 i 个元素为结尾的最大子段和。
-
状态转移方程:dp[i]=max(dp[i],dp[i-1]+a[i]);,即在以 a[i] 结尾的子段中,取最大值。
-
初始化:dp[0] =a[0]。
-
最终结果:maxn = max(dp)。
代码
#include<bits/stdc++.h>
using namespace std;
int a[200010],dp[200010];//dp[i]表示以a[i]结尾的最大连续字段和
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
dp[1]=a[1];//初始化
int maxn=dp[1];
for(int i=2;i<=n;i++){
dp[i]=max(dp[i],dp[i-1]+a[i]);
maxn=max(maxn,dp[i]);
}
cout<<maxn;
return 0;
}