最简单粗暴的最大连续和

c#include <stdio.h>
#include <string.h>


int main()
{
    const int maxn = 1000;
    int n;
    int S[maxn];
    while(~scanf("%d", &n))
    {
        memset(S, 0, sizeof(S));
        for(int i = 1 ; i <= n; i++) scanf("%d", &S[i]);

        int best = S[1];
        for(int i = 1; i <= n; i++)
            for(int j = i; j <= n; j++)
            {
                int sum = 0;
                for(int k = i; k <= j ; k++)
                {
                    sum += S[k];
                }
                best = best > sum ? best : sum;
            }

        printf("%d\n", best);
    }
    return 0;
}

优化。

8.1.1 渐进时间复杂度

渐进时间复杂度计算方法,如何估算时间复杂度。

直接求所有的和,通过和的加减求区间和。

  1. 最大连续和
c#include <stdio.h>
#include <string.h>


int main()
{
    const int maxn = 1000;
    int n;
    int S[maxn];
    while(~scanf("%d", &n))
    {
        int temp;
        memset(S, 0, sizeof(S));
        for(int i = 1 ; i <= n; i++)
        {
            scanf("%d", &temp);
            S[i] = S[i-1] + temp;
        }

        int best;
        for(int i = 0; i <= n; i++)
            for(int j = i; j <= n; j++)
            {
                int temp = S[j] - S[i] ;
                best = best > temp ? best : temp;
            }

        printf("%d\n", best);
    }
    return 0;
}

8.1.3 分治法

c#include <stdio.h>
#include <string.h>


int maxsum(int *A, int x, int y)
{
    int i, m, v, L, R, max;
    if(y - x == 1) return A[x];
    m = x + (y-x)/2;
    int a, b;

    // 求左右最大值
    a = maxsum(A, x, m);
    b = maxsum(A, m, y);
    max = a > b ? a : b;

    // 左右分别占一部分
    v = 0; L = A[m-1];
    for(i = m-1; i >= x; i--)
    {
        v += A[i];
        L = L > v ? L : v;
    }

    v = 0; R = A[m];
    for(i = m; i < y; i++)
    {
        v += A[i];
        R = R > v? R : v;
    }

    return max > (L+R) ? max : (L+R);
}

const int maxn =1000;
int main()
{
    int a[maxn];
    int n;
    int i;
    while(~scanf("%d", &n))
    {
        for (i = 0; i < n; i++) scanf("%d", &a[i]);
        printf("%d\n", maxsum(a, 0, n));
    }

    return 0;
}

动态规划的思想

如果找S[j] - S[i-1]的最大值,就是找S[i-1]的最小。因此只用扫描一次数组。

c#include <stdio.h>
#include <string.h>

const int maxn =1000;
const int INF = 0x3f3f3f3f;

int main()
{
    int a[maxn], s[maxn];
    int n, i, min, max, temp;
    while(~scanf("%d", &n))
    {
        for(i = 1; i <= n; i++) 
            scanf("%d", &a[i]);

        max = min = s[0] = 0;
        for(int i = 1; i <= n; i++)
        {
            s[i] = s[i-1] + a[i];
            temp = s[i] - min;
            if(temp < 0) min = s[i];
            else max = max > temp ? max : temp;
        }

        printf("%d\n", max);
    }
    return 0;
}

svtter
209 声望37 粉丝

更喜欢原型开发


引用和评论

0 条评论