[DP]洛谷P1115最大子段和
题目来源
https://www.luogu.org/problemnew/show/P1115
题目描述
给出一段序列,选出其中连续且非空的一段使得这段和最大。
输入输出格式
输入格式:
第一行是一个正整数 NN ,表示了序列的长度。
第二行包含 NN 个绝对值不大于 1000010000 的整数 A_iAi ,描述了这段序列。
输出格式:
一个整数,为最大的子段和是多少。子段的最小长度为 11 。
输入输出样例
输入样例#1:
7
2 -4 3 -1 2 -4 3
输出样例#1:
4
说明
【样例说明】
2,-4,3,-1,2,-4,32,−4,3,−1,2,−4,3 中,最大的子段和为4,该子段为 3,-1,23,−1,2 .
【数据规模与约定】
对于 40\%40% 的数据,有 N ≤ 2000N≤2000 。
对于 100\%100% 的数据,有 N ≤ 200000N≤200000 。
题解
一般我们在做DP动态规划类问题的思路肯定是:
1、设计状态 把当前的局面表达
2、设计状态转移方程 我从哪里来/要到那里去
对于这题呢就是:
- 设计状态 dp[i]=以a[i]结尾的最大子段和
2、设计状态转移方程 dp[i]=max(dp[i-1]+a[i],a[i])
代码实现:
-
//最大子段和
-
//dp[i]为[1,i]位的最大子段和
-
#include<iostream>
-
#include<cstdio>
-
using namespace std;
-
-
int max(int a,int b){
-
return a>=b?a:b;
-
}
-
int dp[200010],a[200010],ans=-1e9;
-
-
int main(){
-
int n;
-
scanf("%d",&n);
-
if(n!=1){
-
for(int i=0;i<n;i++){
-
scanf("%d",&a[i]);
-
if(i!=0){
-
dp[i]=max(dp[i-1]+a[i],a[i]);
-
//printf("%d\t",dp[i]);
-
ans=max(dp[i],ans);
-
//printf("%d\n",ans);
-
}else dp[0]=a[0];
-
}}else scanf("%d",&ans);
-
printf("%d",ans);
-
return 0;
-
}