• 九度OJ 1527 首尾相连数组的最大子数组和 -- 动态规划


    题目地址:http://ac.jobdu.com/problem.php?pid=1527

    题目描述:

    给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是相连的。数组中一个或多个连续元素可以组成一个子数组,其中存在这样的子数组arr[i],…arr[n-1],arr[0],…,arr[j],现在请你这个ACM_Lover用一个最高效的方法帮忙找出所有连续子数组和的最大值(如果数组中的元素全部为负数,则最大和为0,即一个也没有选)。

    输入:

    输入包含多个测试用例,每个测试用例共有两行,第一行是一个整数n(1=<n<=100000),表示数组的长度,第二行依次输入n个整数(整数绝对值不大于1000)。

    输出:

    对于每个测试用例,请输出子数组和的最大值。

    样例输入:
    6
    1 -2 3 5 -1 2
    5
    6 -1 5 4 -7
    
    样例输出:
    10
    14
    
    来源:
    淘宝2013年校园招聘一面面试题
    #include <stdio.h>
     
    int Max_Sub (int arr[], int n){
        int i;
        int tmp;
        int max;
     
        tmp = max = arr[0];
        for (i=1; i<n; ++i){
            if (tmp > 0)
                tmp += arr[i];
            else
                tmp = arr[i];
            if (tmp > max)
                max = tmp;
        }
        return max;
    }
     
    int Max_Left (int arr[], int n, int * left){
        int i;
        int tmp;
        int max;
     
        tmp = max = arr[0];
        *left = 0;
        for (i=1; i<n; ++i){
            tmp += arr[i];
            if (tmp > max){
                max = tmp;
                *left = i;
            }
        }
        return max;
    }
     
    int Max_Right (int arr[], int n, int * right){
        int i;
        int tmp;
        int max;
     
        tmp = max = arr[n-1];
        *right = 0;
        for (i=n-2; i>=0; --i){
            tmp += arr[i];
            if (tmp > max){
                max = tmp;
                *right = i;
            }
        }
        return max;
    }
     
    int Min_Sub (int arr[], int n){
        int i;
        int tmp;
        int min;
     
        tmp = min = arr[0];
        for (i=1; i<n; ++i){
            if (tmp < 0)
                tmp += arr[i];
            else
                tmp = arr[i];
            if (tmp < min)
                min = tmp;
        }
        return min;
    }
     
    int main(void){
        int n;
        int arr[100000];
        int max;
        int min;
        int left_max;
        int right_max;
        int left;
        int right;
        int mmax;
        int i;
        int flag;
     
        while (scanf ("%d", &n) != EOF){
            flag = 0;
            for (i=0; i<n; ++i){
                scanf ("%d", &arr[i]);
                if (arr[i] > 0)
                    flag = 1;
            }
            if (flag == 1){
                max = Max_Sub (arr, n);
                left_max = Max_Left (arr, n, &left);
                right_max = Max_Right (arr, n, &right);
                if (left > right){
                    mmax = 0;
                    for (i=0; i<n; ++i)
                        mmax += arr[i];
                    min = Min_Sub (arr, n);
                    mmax -= min;
                }
                else
                    mmax = left_max + right_max;
                printf ("%d
    ", (max > mmax) ? max : mmax);
            }
            else
                printf ("0
    ");
        }
     
        return 0;
    }
    /**************************************************************
        Problem: 1527
        User: 简简单单Plus
        Language: C
        Result: Accepted
        Time:80 ms
        Memory:1232 kb
    ****************************************************************/
    
  • 相关阅读:
    洛谷—— P2234 [HNOI2002]营业额统计
    BZOJ——3555: [Ctsc2014]企鹅QQ
    CodeVs——T 4919 线段树练习4
    python(35)- 异常处理
    August 29th 2016 Week 36th Monday
    August 28th 2016 Week 36th Sunday
    August 27th 2016 Week 35th Saturday
    August 26th 2016 Week 35th Friday
    August 25th 2016 Week 35th Thursday
    August 24th 2016 Week 35th Wednesday
  • 原文地址:https://www.cnblogs.com/liushaobo/p/4373814.html
Copyright © 2020-2023  润新知