最大字段和

题目描述

给出一个长度为 nn 的序列 aa,选出其中连续且非空的一段使得这段和最大。

输入格式

第一行是一个整数,表示序列的长度 nn。

第二行有 nn 个整数,第 ii 个整数表示序列的第 ii 个数字 a_iai​。

输出格式

输出一行一个整数表示答案。

输入输出样例

输入 #1复制

7
2 -4 3 -1 2 -4 3

输出 #1复制

4

说明/提示

样例 1 解释

选取 [3, 5][3,5] 子段 \{3, -1, 2\}{3,−1,2},其和为 44。

数据规模与约定

  • 对于 40\%40% 的数据,保证 n \leq 2 \times 10^3n≤2×103。
  • 对于 100\%100% 的数据,保证 1 \leq n \leq 2 \times 10^51≤n≤2×105,-10^4 \leq a_i \leq 10^4−104≤ai​≤104。

第一种方法是贪心,然后去特判全是负数的情况

第二种方法是动态规划

方法1:

#include 
typedef long long ll;
const int M=2e5+5;
using namespace std;
ll n;
ll a[M],b[M];
ll sum;
ll ans=-1e10;
int main()
{
    int i;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=b[i-1]+a[i];
        if(b[i]<0)
        {
            b[i]=0;
        }
        ans=max(ans,b[i]);
    }
    int num=-1e10;
    if(ans==0)
    {
        for(i=1;i<=n;i++)
        {
            if(a[i]>num)
            {
                num=a[i];
            }
        }
          cout<

方法2:

#include
using namespace std;
typedef long long ll;
int n;
const int maxn=2e5+5;
ll a[maxn];
ll dp[maxn];
ll ans=-1e18;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        dp[i]=max(dp[i-1]+a[i],a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        ans=max(ans,dp[i]);
    }
    cout<

你可能感兴趣的:(c++,算法,动态规划)