[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、设计状态转移方程      我从哪里来/要到那里去

对于这题呢就是:

  1. 设计状态     dp[i]=以a[i]结尾的最大子段和

2、设计状态转移方程      dp[i]=max(dp[i-1]+a[i],a[i])

代码实现:

  1. //最大子段和  
  2. //dp[i][1,i]位的最大子段和  
  3. #include<iostream>  
  4. #include<cstdio>  
  5. using namespace std;  
  6.     
  7. int max(int a,int b){  
  8.     return a>=b?a:b;  
  9. }   
  10. int dp[200010],a[200010],ans=-1e9;   
  11.     
  12. int main(){  
  13.     int n;  
  14.     scanf("%d",&n);  
  15.     if(n!=1){  
  16.     for(int i=0;i<n;i++){  
  17.         scanf("%d",&a[i]);  
  18.         if(i!=0){  
  19.             dp[i]=max(dp[i-1]+a[i],a[i]);  
  20.             //printf("%d\t",dp[i]);  
  21.             ans=max(dp[i],ans);  
  22.             //printf("%d\n",ans);  
  23.         }else dp[0]=a[0];  
  24.     }}else scanf("%d",&ans);  
  25.     printf("%d",ans);  
  26.     return 0;  
  27. }  
posted @ 2018-08-04 19:11  Chicago_01  阅读(219)  评论(0编辑  收藏  举报