一、贪心
贪心算法是两极分化很严重的算法。简单的问题会让你觉得理所应当,难一点的问题会让你怀疑人生。在解决贪心问题我们有时不仅要理解贪心策略,也要学会证明贪心策略的正确性来提高思维的严密性。
1.1 什么是贪心算法
贪心算法也称作贪心策略:企图用局部最优找出全局最优。 (1)把解决问题的过程分成若干步; (2)解决每一步时,都选择"当前看起来最优的"解法; (3)希望"得到全局的最优解"
1.2 贪心算法的特点
总体特点:目光短浅 (1)对于绝大多数题目,贪心策略的提出并不是很难,难的是证明它是正确的。因为贪心算法相较于暴力枚举,每一步并不是把所有情况都考虑进去,而是只考虑当前看起来最优的情况。但是局部最优并不等于全局最优,所以我们必须要能严谨的证明我们的贪心策略是正确的。一般证明策略有:反证法,数学归纳法,交换论证法等等。 (2)当问题的场景不同时,贪心的策略也会不同。因此,贪心策略的提出是没有固定的套路和模板的。
1.3 如何学习贪心?
(1)重点放在各种各样的策略上,把各种策略当成经验来吸收; (2)在平常学习的时候,我们尽可能的证明一下这个贪心策略是否正确,这样有利于培养我们严谨的思维。
二、简单贪心的经典算法题
2.1 最大子段和
2.1.1 题目
链接:最大子段和

2.1.2 算法原理
贪心想法:从前往后累加,我们会遇到下面两种情况: (1)目前的累加和 > 0:那么当前累加和还会对后续的累加和做出贡献,那我们就继续向后累加,然后更新结果。 (2)目前的累加和 < 0:对后续的累加和做不了一点贡献,直接大胆舍弃计算过的这一段,把累加和重置为 0,然后继续向后累加。 这样我们在扫描整个数组一遍之后,就能更新出最大子段和
注:考虑到如果结果可能为负数所以可以在累加过程中一边更新结果不用做过多断判断。全为负数时即为求最大值。
2.1.3 代码
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
LL a[N];
int main(){
int n; cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
LL sum = 0;
LL ret = -1e20;
( i = ; i <= n; i++){
sum += a[i];
ret = (ret, sum);
(sum < ) sum = ;
}
cout << ret << endl;
;
}





