最大子段和

给出一个长度为 n n n 的序列 a a a,选出其中连续且非空的一段使得这段和最大。

如果均为负数,则输出 0 0 0

分析

考虑 dp

状态

d p i dp_i dpi 为以 i i i 结尾的最大子段和。

状态转移方程

有两种方案:

  • 可以自己成为一个最大子段和,就是 a i a_i ai
  • 可以跟前面的最大子段和拼起来,就是 d p i − 1 + a i dp_{i-1}+a_i dpi1+ai

两者取最大值。

答案循环找最大值即可。

代码

#include 
#define inf LONG_LONG_MAX
#define int long long 

using namespace std;

const int N = 5 * 1e5 + 5;

int n, a[N], dp[N], maxn = -inf;

signed main(){
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		dp[i] = a[i];//初始状态
	}
	for(int i = 2; i <= n; i ++){
		dp[i] = max(dp[i], dp[i - 1] + a[i]);
		maxn = max(maxn, dp[i]);
	}
	if(maxn < 0){
		cout << 0;
	}else{
		cout << maxn;
	}
  return 0;
}

你可能感兴趣的:(动态规划,算法)