洛谷P3009 [USACO11JAN]Profits S

原题链接
这道题实际上是最大连续子序和问题,解决方案有很多,这里介绍两种。
一、动态规划
这里我们用一个一维数组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;
}
发布了14 篇原创文章 · 获赞 3 · 访问量 151

猜你喜欢

转载自blog.csdn.net/IMDASHUAI/article/details/104742420