• 8. 最大子列和


    问题描述:对给定数组A,寻找A的和最大的非空连续子数组。

    输入格式:输入的第一行包括一个整数n,代表数组中的元素个数,接下来的一行包含n个整数(可以包含负数),以空格分隔。

    输出格式:一个整数,表示最大的连续子数组的和。

    样例输入:

    9

    2  4  -7  5  2  -1  2  -4  3

    样例输出:

    8

    思路:1.分治法

      分解:把数组从中间位置划分成两个子数组。

      解决:使用分治法递归地求解这两个子数组的最大子数组。当规模缩小到子数组长度为1时,直接返回该元素的值。

      合并:求解跨越两个子数组的最大子数组,即跨越这个相邻子数组合成的数组中点的最大子数组,并与之前得到的结果进行比较,选取和最大者。

      时间复杂度:O(NlogN)

    Code:

    #include<iostream>
    #include<vector>
    using namespace std;
    vector<int> a;
    int n;
    int solve(int L, int R){
        if (L == R) return a[L];
        int maxL = 0, maxR = 0, maxMid = 0;
        int mid = (L + R) / 2;
        int sumL = 0, sumR = 0, maxSumL = 0, maxSumR = 0;
        maxL = solve(L, mid);
        maxR = solve(mid+1, R);
        for (int i = mid; i >= 0; i--){
            sumL += a[i];
            if (sumL > maxSumL)
                maxSumL = sumL;
        } 
        for (int i = mid+1; i <= R; i++){
            sumR += a[i];
            if (sumR > maxSumL)
                maxSumL = sumR;
        }
        return max(max(maxL, maxR), maxSumL+maxSumR);
    }
    
    int main(){
        scanf("%d", &n);
        a.resize(n);
        for(int i = 0; i < n; i++)
            scanf("%d", &a[i]);
        cout << solve(0, n-1);
        return 0;
    }

      2.动态规划

      dp[n] 表示以第n个数为结尾的最大子列和。

      dp[n] = max(0, dp[n-1]) + a[n]。

      时间复杂度为O(N)

      

    #include<iostream>
    using namespace std;
    int n;
    int main(){
        scanf("%d", &n);
        int x, sum = 0, maxSum = 0;
        for(int i = 0; i < n; i++){
            cin >> x;
            sum += x;
            if (sum > maxSum) maxSum = sum;
            else if (sum < 0) sum = 0;
        } 
        cout << maxSum;
        return 0;
    }
  • 相关阅读:
    python小程序之购物系统
    列表,元祖,字典的使用
    几个python小程序
    default
    RTTI
    man
    养喜神去杀机
    IDEA+Maven+Git
    入门
    CheckStyle简介
  • 原文地址:https://www.cnblogs.com/astonc/p/11705274.html
Copyright © 2020-2023  润新知