• sdut3664顺序表应用7:最大子段和之分治递归法


    Description

    给定n(1<=n<=50000)个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n。 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。

    注意:本题目要求用分治递归法求解,除了需要输出最大子段和的值之外,还需要输出求得该结果所需的递归调用总次数。

    递归调用总次数的获得,可以参考以下求菲波那切数列的代码段中全局变量count的用法:

    #include
    int count=0;
    int main()
    {
    int n,m;
    int fib(int n);
    scanf("%d",&n);
    m=fib(n);
    printf("%d %d\n",m,count);
    return 0;
    }
    int fib(int n)
    {
    int s;
    count++;
    if((n==1)||(n==0)) return 1;
    else s=fib(n-1)+fib(n-2);
    return s;
    }

    Input

    第一行输入整数n(1<=n<=50000),表示整数序列中的数据元素个数;

    第二行依次输入n个整数,对应顺序表中存放的每个数据元素值。

    Output

    一行输出两个整数,之间以空格间隔输出:

    第一个整数为所求的最大子段和;

    第二个整数为用分治递归法求解最大子段和时,递归函数被调用的总次数。

    Sample

    Input 

    6
    -2 11 -4 13 -5 -2

    Output 

    20 11

    Hint

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 int num;
     5 
     6 int max(int x, int y)
     7 {
     8     if(x<y) return y;
     9     else return x;
    10 }
    11 
    12 int fenzhi(int a[], int left, int right)
    13 {
    14     num++;
    15     if(left>right) return 0;
    16     if(left==right) return max(a[left], 0);
    17     int suml, sumr, sum, re, rel, rer, i;
    18     int mid = (left+right)/2;
    19     rel = fenzhi(a, left, mid); ///单纯从最大字段和来讲mid-1也可,不过根据题目给出的样例中的次数来看应当是mid
    20     rer = fenzhi(a, mid+1, right);
    21     suml = 0;
    22     sum = 0;
    23     for(i=mid-1;i>=left;i--)
    24     {
    25         sum+=a[i];
    26         suml = max(suml, sum);
    27     }
    28     sumr = 0;
    29     sum = 0;
    30     for(i=mid+1;i<=right;i++)
    31     {
    32         sum+=a[i];
    33         sumr = max(sumr, sum);
    34     }
    35     sum = suml + sumr + a[mid];
    36     re = max(max(rel, rer), sum);
    37     return re;
    38 }
    39 
    40 
    41 int main()
    42 {
    43     int n, i;
    44     int a[50005];
    45     scanf("%d", &n);
    46     for(i=0;i<n;i++)
    47     {
    48         scanf("%d", &a[i]);
    49     }
    50     num = 0;
    51     int re = fenzhi(a, 0, n-1);
    52     printf("%d %d\n", re, num);
    53     return 0;
    54 }
  • 相关阅读:
    C#遍历List并删除某个或者几个元素的方法
    7月清北学堂培训 Day 4
    7月清北学堂培训 Day 3
    7月清北学堂培训 Day 2
    7月清北学堂培训 Day 1
    P1383 高级打字机
    P2401 不等数列
    P1412 经营与开发
    P1314 聪明的质监员
    2019.7.9 校内测试 T3 15数码问题
  • 原文地址:https://www.cnblogs.com/0xiaoyu/p/16261357.html
Copyright © 2020-2023  润新知