zoukankan      html  css  js  c++  java
  • C

    Time Limit 10 ms
    Mem. Limit 400 KiB

    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

    解析:

    分治求最大子段和,将每个子段分成左右两个部分,然后分别求最大子段,最后取左子段和、右子段和、从中间开始字段和,取最大的。

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    //#include <bits/stdc++.h>
    
    using namespace std;
    
    int data[512345];
    int num;
    //求子段的最大和,注意左子段从左向中间加,右子段从右向中间加。
    int getsum(int l, int r, int mid){
        int sum1, sum2, sum, i;
        sum1 = sum = 0;
        for(i=l; i<=mid; i++){
            sum += data[i];
            if(sum<0)
                sum = 0;
        }
        sum1 = sum;
        sum2 = sum = 0;
        for(i=r; i>mid; i--){
            sum += data[i];
            if(sum<0)
                sum = 0;
        }
        sum2 = sum;
        return sum1 + sum2;
    }
    //求最大子段和。
    int getmax(int l,int r){
        num ++;
        if(l==r)
            return data[l];
        int mid, x, y, sum;
        mid = (l + r) / 2;
        x = getmax(l, mid);
        y = getmax(mid+1, r);
        sum = getsum(l, r, mid);
        return max(sum,max(x,y));
    }
    
    int main(){
        int n, i, sum;
        scanf("%d",&n);
        for(i=1; i<=n; i++)
            scanf("%d",&data[i]);
        num = 0;
        sum = getmax(1,n);
        printf("%d %d
    ",sum,num);
        return 0;
    }
    
  • 相关阅读:
    完美解决微信端设置title失败问题
    linux下的find&&grep查找命令
    微信开发二三事
    干掉chrome下input恶心的黄色背景
    关于.gitignore文件使用说明
    HTTPie:一个不错的 HTTP 命令行客户端
    退出登录功能改变window的rootviewcontroller输入框键盘不会收起
    coredata操作工具
    并发编程gcd粗暴记忆法
    网友的百度移动云可穿戴部门的面试经历
  • 原文地址:https://www.cnblogs.com/luoxiaoyi/p/13716806.html
Copyright © 2011-2022 走看看