PAT 1007 最大子段和——一般方法与动态规划法

求解最大子段和

原题链接
求解最大子段和有三种方法:

  1. 遍历数组,在遍历的过程中更新比较最大和
  2. 分治法,考虑最大子段出现在左边、右边、以及中间的情形
  3. 动态规划法,其中dp[j]是以j为结尾的子段和,由此可列出状态转移方程dp[j]=max(dp[j-1]+a[j],a[j]),这题还需要输出最大子段的始末元素,设置一个start数组,start[j]保存以j为结尾的子段和起始位置

ps:以下为遍历方法与动态规划法的AC代码

解法一(遍历)

#include <iostream>

using namespace std;

int main()
{
    int N, a[10000], low=0, high=0, maxsum=0;
    int nowlow, nowhigh, nowsum;
    bool flag = false;
    cin >> N;
    for (int i=0; i<N; i++)
    {
        cin >> a[i];
        if (a[i] >= 0)
            flag = true;
    }
    if (flag == false)
    {
        cout<<0<<" "<<a[0]<<" "<<a[N-1];
        return 0;
    }
    nowlow=0,nowhigh=0,nowsum=0;
    while(nowhigh != N)
    {
        if (nowsum+a[nowhigh] >= 0)
        {
            nowsum += a[nowhigh];
            if (nowsum > maxsum)
            {
                low = nowlow;
                high = nowhigh;
                maxsum = nowsum;
            }
        }
        else
        {
            nowlow = nowhigh+1;
            nowsum = 0;
        }
        nowhigh++;
    }
    if (maxsum == 0)
        cout<<maxsum<<" "<<0<<" "<<0;
    else
        cout<<maxsum<<" "<<a[low]<<" "<<a[high];
    return 0;
}

解法3(动态规划)

#include <iostream>
#include <cstdio>

using namespace std;

const int maxk = 10001;

int main()
{
    int K, a[maxk], dp[maxk], start[maxk];
    scanf("%d",&K);
    for (int i=1; i<=K; i++)
        scanf("%d",&a[i]);
    dp[1] = a[1];
    start[1] = 1;
    for (int i=2; i<=K; i++)
    {
        if (dp[i-1]+a[i] > a[i])
        {
            dp[i] = dp[i-1]+a[i];
            start[i] = start[i-1];
        }
        else
        {
            dp[i] = a[i];
            start[i] = i;
        }
    }
    int maxdp = dp[1],maxi = 1;
    for (int i=2; i<=K; i++)
    {
        if (dp[i]>maxdp)
        {
            maxdp = dp[i];
            maxi = i;
        }
    }
    if (maxdp < 0)
        printf("0 %d %d",a[1], a[K]);
    else
        printf("%d %d %d",maxdp, a[start[maxi]], a[maxi]);
    return 0;
}

end

猜你喜欢

转载自blog.csdn.net/adventural/article/details/86744878
今日推荐