原题链接
这道题实际上是最大连续子序和问题,解决方案有很多,这里介绍两种。
一、动态规划
这里我们用一个一维数组a来储存选择第i个元素的最大连续子序和。这样就有转移方程为a[i]=max(a[i],a[i]+a[i-1]),前者表示不选i之前的元素,后者表示选择i之前的元素。这里保证了连续性(思考一下为什么)
代码:
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int> a(n+1);
a[0]=0;
int ans=INT_MIN;
for(int i=0;i<n;i++){
cin>>a[i];
a[i]=max(a[i],a[i]+a[i-1]);
ans=max(ans,a[i]);
}
cout<<ans;
return 0;
}
当然这个代码空间复杂度可以优化成O(1)
代码:
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int main()
{
int n;
cin>>n;
int f=0,now;
int ans=INT_MIN;
for(int i=0;i<n;i++){
cin>>now;
now=max(now,now+f);
f=now;
ans=max(ans,now);
}
cout<<ans;
return 0;
}
二、贪心
这个的正确性不太好看出,附上代码,(溜…)
#include<iostream>
#include<vector>
#include<climits>
using namespace std;
int max(int a, int b) {
return a > b ? a : b;
}
int main()
{
int n;
cin >> n;
vector<int> a(n);
int ans = INT_MIN;
int total = 0;
for (int i = 0; i < n; i++) {
cin >> a[i];
total += a[i];
ans = max(ans, total);
if (total < 0)
total = 0;
}
cout << ans;
return 0;
}