【解题报告】洛谷P1115 最大子段和
题目链接
https://www.luogu.com.cn/problem/P1115
思路
我们有两种方法
- 贪心
我们一直输入,然后一直加法,如果 (sum < 0) 就说明这是不合法的,从头再来,我们边记录,边加法,然后最后记录到的最大值就是 (ans) 记录的值了
#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]))
然后我们用一个滚动数组滚一下,然后就变成贪心了
别人的代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n[200001],p,ans[200001]={0};
int sum=-9999999;//|x|<=10000 QWQ
cin>>p;
for(int i=1;i<=p;i++)
{
cin>>n[i];//输入
ans[i]=max(ans[i-1]+n[i],n[i]);//DP
sum=max(sum,ans[i]);//取最大值也同时进行,节约时间
}
cout<<sum;//直接输出
return 0;
}