【解题报告】洛谷P1115 最大子段和
题目链接
https://www.luogu.com.cn/problem/P1115
思路
我们有两种方法
- 贪心
我们一直输入,然后一直加法,如果 sum<0 就说明这是不合法的,从头再来,我们边记录,边加法,然后最后记录到的最大值就是 ans 记录的值了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cstring> using namespace std; int n; int ans=-999; int main() { std::ios::sync_with_stdio(false); cin>>n; int sum=0; for(int i=1;i<=n;i++) { int a; cin>>a; sum+=a; ans=max(ans,sum); if(sum<0) sum=0; } cout<<ans<<endl; return 0; }
|
- 动态规划
实际上就是贪心吧
我们设 f[i] 表示从1到 i 的最大字段和
于是我们就有 f[i]=max(f[i−1]+a[i],a[i])
然后我们用一个滚动数组滚一下,然后就变成贪心了
别人的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include<bits/stdc++.h> using namespace std; int main() { int n[200001],p,ans[200001]={0}; int sum=-9999999; cin>>p; for(int i=1;i<=p;i++) { cin>>n[i]; ans[i]=max(ans[i-1]+n[i],n[i]); sum=max(sum,ans[i]); } cout<<sum; return 0; }
|