zoukankan      html  css  js  c++  java
  • 第二章上机实验报告

    7-1 最大子列和问题 (20分)

    给定K个整数组成的序列{ N1​​, N2​​, ..., NK​​ },“连续子列”被定义为{ Ni​​, Ni+1​​, ..., Nj​​ },其中 1。“最大子列和”则被定义为所有连续子列元素的和中最大者。

    例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

    对最大子列和的分析: 我对于题目的理解是这样子的:给定一个数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),然后返回其最大和

     1 int maxWidth(int left, int right){
     2     //递归算法--每个递归内部包含三个求值操作
     3     //1、中位数左边(mid)的最大序列和
     4     //2、中位数右边(mid+1)的最大序列和
     5     //3、相对中位数来说跨了左右的最大序列和
     6     
     7     //每个递归结束条件的判断
     8     if(left==right){
     9         return a[left];
    10     }
    11     int mid = (left+right)/2;
    12     int lch = maxWidth(left, mid);//计算左边的最大序列和
    13     int rch = maxWidth(mid+1, right);//计算右边的序列和
    14     //计算跨左右的最大子序列和
    15     int lnum, rnum;
    16     int ln = 0;//辅助判断
    17     lnum=a[mid];
    18     //计算从 mid 开始向左累加的最大序列和
    19     for(int i=mid;i>=left;i--){
    20         ln+=a[i];
    21         if(ln>lnum)  lnum=ln;
    22     }
    23     rnum=a[mid+1];
    24     ln=0;
    25     //计算从 mid+1 开始向右累加的最大序列和
    26     for(int i=mid+1;i<=right;i++){
    27         ln+=a[i];
    28         if(ln>
    29         rnum)  rnum=ln;
    30     }
    31     return maxNum(rnum+lnum, lch, rch);
    32 }
    View Code

    上面是我的核心代码,利用了递归分治的思想,每次递归进行三大步的操作,第一步在当前中心点向左搜索找出最大子序列和,第二步在当前中心点向右搜索找出最大子序列和,第三步在中心点下标分别向右和向左遍历找出最大子序列和,上述三者的最大值作为本层递归的返回值给上一层递归进行调用。

    时间复杂度O(n*lg n)   这里用主定理去求解 T(n) = 2*T(n/2) + O(n)

    每次将问题分解为两个子问题,每个子问题的长度为原问题的一半, O(n)包含了问题分解和子问题解合并的代价,从代码上来看,分解的过程包含了一些 O(1)的操作,然后有两个循环体,一个是从头到中间,另外一个是从中间到尾部, 所以加起来时间复杂度为 O(n), O(n) = n的 logb a次方 , log b a = 1, 因为 a=b时要成一个 lgn 所以总的时间复杂度为 O(n*lg n) 

    心得:有些地方要看清楚题目的描述,比如说全为负数的时候返回的是0 而不是最大的负数,之前想当然的认为是返回最大负数。

  • 相关阅读:
    Jzoj4721 LCS
    Jzoj4721 LCS
    Bzoj3196 二逼平衡树
    Bzoj3196 二逼平衡树
    Jzoj4715 树上路径
    Jzoj4715 树上路径
    031下一个排列
    汉诺塔问题【递归】
    求全排列和组合问题
    030串联所有单词并匹配
  • 原文地址:https://www.cnblogs.com/jintao1990/p/13791773.html
Copyright © 2011-2022 走看看