最大字段和
算法:DP动态规划
题目描述
最大子段和问题是一个经典的算法问题,它要求在一个可能包含负整数的序列中找到一个连续子段,使得这个子段的整数和最大。例如,序列 (-2, 11, -4, 13, -5, -2) 的最大子段和是 {11, -4, 13},其和为20。
主要思想:
DP的最核心的思想就是到目前为止的最优解:那么当前的最优解就等于上一个的最优解 加上当前的值(如果值为正的话)
当前的最优解 dp
到目前为止的最优解 ans
循环每一个 元素 xi i属于 1 ~ n
如果 目前的 xi 大于 0:
dp 加上 xi; // 这个很好理解:一旦当前值是正数:加上就得到答案
否则:
dp 等于 xi; // 这个也不难看出:一旦加上当前值不是最优解,那么重新修改起点
如果 ans 小于 当前dp:更新ans为dp
这个我用中文解释的 伪代码 已经很详细了
如果用DP的角度来想的活那么状态转移方程就是
dp[i] = max(dp[i], dp[i - 1] + arr[i]);
这样就可以完成我们的最大子段和了
以下是代码
#include <iostream>
using namespace std;
int dp = 0;
int arr[1000010];
int n;
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++)
{
cin >> arr[i];
}
int ans = 0;
for (int i = 1; i <= n; i ++)
{
if (dp > 0)
{
dp += arr[i];
}
else
{
dp = arr[i];
}
if (ans <= dp) ans = dp;
}
cout << ans << endl;
return 0;
}