题目 : 最大子段和 - 洛谷
贪心思想:
如果字段和为负数,那么一定会使后面一个数减小,不如舍弃,从下一个数开始累加,定义a数组和f数组,定义res更新最大值,直接输出
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
int n;
int a[N];
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
int sum=0,max=-10000000;
for(int i=0;i<n;i++){
sum+=a[i];
if(sum>max) max=sum;
if(sum<0) sum=0;
}
cout<<max;
return 0;
}
DP思想:
1.状态分析:(找到所有集合以及符合条件的集合+属性)
2.状态计算(集合划分+写出状态转移方程) 假设 f[i] 为以a[i]结尾的集合最大的和,
递推公式:f[i]=max(f[i-1]+a[i],a[i]) 划分方式为有可能a[i]本身为最大值,不加之前的
最后遍历一遍a[i] ,找到最大值
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+5;
int n;
int a[N];
int f[N];
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
f[i]=max(f[i-1]+a[i],a[i]);
}
int res=-10000000;
for(int i=0;i<n;i++){
res=max(res,f[i]);
}
cout<<res;
return 0;
}