洛谷 P1115 最大子段和
生活随笔
收集整理的这篇文章主要介绍了
洛谷 P1115 最大子段和
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
【题目链接】
洛谷 P1115 最大子段和
【题目考点】
1. 动态规划:线性动规
- 最大子段和
【解题思路】
解法1:线性动规
子段或子串指的是序列中连续的多个元素,子序列是指序列中可以不连续的多个元素。
1. 状态定义
集合:所有子段
限制:子段所在区间范围
属性:加和
条件:最大
统计量:加和
状态定义:dp[i]为以i为结尾的加和最大的子段的加和。
2. 状态转移方程
记a[i]为第i个元素的值
分割集合:考虑以第i元素为结尾的子段
- 子集1:第i元素自己作为一个子段,dp[i] = a[i]
- 子集2:如果第i元素和其左边一些元素构成子段,那么第i元素左边的子段为以第i-1元素为结尾的子段,以第i-1元素为结尾的子段中加和最大的子段的加和为dp[i-1],在这个子段后面添加第i元素,这个以i为结尾的子段加和为dp[i]=dp[i-1]+a[i]
以上二者取最大值。
3. 结果输出
题目要求的是最大子段和,就是以每个位置为结尾的最大子段和中的最大值,即为求dp数组的最大值。
解法2:前缀和
求出原序列的前缀和,保存在s数组中。s[i]表示前i个数的和。
最大子段和即为:满足j>i的s[j]-s[i]的最大值。
mi为数组s在下标1~i中的最小值。那么s[i]-mi即为以i为结尾的子段的最大子段和。
最大子段和为以每个位置为结尾的最大子段和中的最大值。
i从1循环到n,不断更新mi,保持mi为s[1]~s[i]中的最小值,求s[i]-mi的最大值。
解法3:双指针
顺序遍历数组,当前已经选择了以第i-1元素为结尾的子段,该子段和为s,看是否把第i个元素a[i]加入到子段中。
- 如果已有子段的和为负数,即s<0,那么s+a[i] < a[i],也就是说第i元素自己作为一个子段的加和,要比将其接到前一个子段的末尾构成的子段的加和要大。所以此时子段和应该从s变为a[i]
- 如果已有的子段和大于等于0, 即s>=0,那么s+a[i] >= a[i],应该将第i元素接到前一个子段的末尾,构成以第i元素为结尾的子段,子段和从s变为s+a[i]。
在遍历过程中,求所有出现的子段和的最大值。
该算法实际是一种双指针(尺取法)算法,子段的第一个元素的下标为l,最后一个元素的下标为r,当前子段和为负数,则l改变,否则r改变。这里思考时借助了双指针的思想,但代码中并不需要写出双指针。
【题解代码】
解法1:线性动规
#include<bits/stdc++.h> using namespace std; #define N 200005 #define INF 0x3f3f3f3f int a[N], dp[N];//dp[i]:以i为结尾的加和最大的子段的加和 int main() {int n, mx = -INF;cin >> n;for(int i = 1; i <= n; ++i)cin >> a[i];for(int i = 1; i <= n; ++i)dp[i] = max(a[i], a[i] + dp[i-1]);for(int i = 1; i <= n; ++i)mx = max(mx, dp[i]);cout << mx;return 0; }解法2:前缀和
#include<bits/stdc++.h> using namespace std; #define N 200005 #define INF 0x3f3f3f3f int a[N], s[N]; int main() {int n, mi = 0, mxSum = -INF;cin >> n;for(int i = 1; i <= n; ++i){cin >> a[i];s[i] = s[i-1] + a[i];}for(int i = 1; i <= n; ++i){mxSum = max(mxSum, s[i] - mi);mi = min(mi, s[i]);}cout << mxSum;return 0; }解法3:双指针
#include<bits/stdc++.h> using namespace std; #define N 200005 #define INF 0x3f3f3f3f int a[N], s; int main() {int n, mi = 0, mxSum = -INF;cin >> n;for(int i = 1; i <= n; ++i)cin >> a[i];for(int i = 1; i <= n; ++i){if(s < 0)s = a[i];elses += a[i];mxSum = max(mxSum, s);}cout << mxSum;return 0; }总结
以上是生活随笔为你收集整理的洛谷 P1115 最大子段和的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 信息学奥赛一本通 1844:【06NOI
- 下一篇: 信息学奥赛一本通 1226:装箱问题 |