洛谷 P1115 最大子段和 题解
原题链接点这里
题目描述
给出一个长度为 $n$ 的序列 $a$,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度 $n$。
第二行有 $n$ 个整数,第 $i$ 个整数表示序列的第 $i$ 个数字 $a_i$。
输出格式
输出一行一个整数表示答案。
样例 #1
样例输入 #1
7
2 -4 3 -1 2 -4 3
样例输出 #1
4
提示
样例 1 解释
选取 $[3, 5]$ 子段 ${3, -1, 2}$,其和为 $4$。
数据规模与约定
- 对于 $40\%$ 的数据,保证 $n \leq 2 \times 10^3$。
- 对于 $100\%$ 的数据,保证 $1 \leq n \leq 2 \times 10^5$,$-10^4 \leq a_i \leq 10^4$。
介绍
这里可以用dp解决。状态也是第i个选不选,f[i]代表的是以i为结尾前面的最大子序列是多少,f[i] = max(f[i - 1] + a[i], a[i])如果前面i-1的再加上a[i]还比a[i]小,那么就选这个a[i],然后res更新一下。
源码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define endl "\n"
const int N = 2e5 + 10;
const int M = 110;
int n;
int a[N],f[N];
void solve()
{
cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
int res = -0x3f3f3f3f;
for (int i = 1; i <= n; i ++ )
{
f[i] = max(f[i - 1] + a[i], a[i]);
res = max(res, f[i]);
}
cout << res << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
solve();
return 0;
}
版权声明:
作者:徐锦桐
链接:https://www.xujintong.com/2023/02/20/142/
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
作者:徐锦桐
链接:https://www.xujintong.com/2023/02/20/142/
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
THE END