zoukankan      html  css  js  c++  java
  • 3664顺序表应用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 ",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 <iostream>
     2 #include <stdio.h>
     3 #include <string>
     4 #include <string.h>
     5 #include <algorithm>
     6 #include <math.h>
     7 #include <map>
     8 #include <vector>
     9 
    10 using namespace std;
    11 
    12 int a[50005], num;
    13 
    14 int op(int l, int r)
    15 {
    16     num++;
    17     if(l==r) return max(0, a[l]);
    18     else
    19     {
    20         int mid, ll, rr, mm, rel, rer, sum, re, i;
    21         mid = (l+r)/2;
    22         rel = op(l, mid);
    23         rer = op(mid+1, r);
    24         sum = 0;
    25         ll = 0;
    26         for(i=mid-1; i>=l; i--)
    27         {
    28             sum += a[i];
    29             if(sum > ll) ll = sum;
    30         }
    31         sum = 0;
    32         rr = 0;
    33         for(i=mid+1;i<=r;i++)
    34         {
    35             sum += a[i];
    36             if(sum > rr) rr = sum;
    37         }
    38         mm = ll + rr + a[mid];
    39         re = max(max(rel, rer), mm);
    40         return re;
    41     }
    42 }
    43 
    44 int main()
    45 {
    46     int n, re, i;
    47     scanf("%d", &n);
    48     for(i=0;i<n;i++)
    49     {
    50         scanf("%d", &a[i]);
    51     }
    52     num = 0;
    53     re = op(0, n-1);
    54     printf("%d %d
    ", re, num);
    55     return 0;
    56 }
  • 相关阅读:
    CSS3 transition 过度
    CSS3 2D转换
    jQuery 选择器
    bootstrap、qjuery、插件 、字体网页
    利用jquery.backstretch插件,背景切换
    js 背景自动切换
    Jquery
    分析动态网页请求爬取腾讯视频评论
    追女神助手v0.1
    动态加载网页的爬取总结
  • 原文地址:https://www.cnblogs.com/0xiaoyu/p/14089668.html
Copyright © 2011-2022 走看看