分治法(求最大子序列和)

 1 //求出最大子序列 4 ,-3,5,-2,-1,2,6,-2
 2 #include <stdio.h>
 3 int max (int a,int b,int c)
 4 {
 5     int ret;
 6     if(a > b)
 7     {
 8         ret = a;
 9     }else
10     if(a <= b)
11     {
12         ret = b;
13     }
14     if(ret >= c)
15     return ret;
16     else
17     return c;
18 }
19  int Findmaxsum(int box[],int size,int left,int right)      //参数(数组名,数组大小,左边界,右边界)
20 {
21     int mid = (right + left) / 2;
22     if(left == right)                                        //分治递归要注意出口条件
23     {
24         return box[left];
25     }
26     int leftsum = Findmaxsum(box,size,left,mid );           //求出左半区最大子序列和 ,要有递归信任,不要纠结层层深入,假设该函数是正确的。
27     int rightsum = Findmaxsum(box,size,mid + 1,right);       //求出右半区最大子序列和
28     int leftbordersum = 0;
29     int rightbordersum = 0;
30     int i;
31     int thissum = 0;
32     for(i = mid + 1 ;i <= right;i++)                         //求出含有中间分界点的右半区最大子序列和  (如果最大子序列横跨中间分界点,那么肯定包含中间分界点,)
33     {
34         thissum += box[i];
35         if(rightbordersum < thissum)
36         {
37             rightbordersum = thissum;
38         }
39      }
40      thissum = 0;
41      for(i = mid ;i >= left;i--)                          //求出含有中间分界点的左半区最大子序列和
42      {
43          thissum += box[i];
44          if(leftbordersum < thissum)
45          {
46              leftbordersum = thissum;
47          }
48      }
49      int midsum = leftbordersum + rightbordersum;               //横跨左右半区最大子序列和
50      return max(midsum,leftsum,rightsum);                        //左半区最大子序列和,右半区最大子序列和,跨半区最大子序列和,三者中最大的为所求者
51
52
53 }
54 int main ()
55 {
56     int box[8] = {4,-3,5,-2,-1,2,5,-2};
57     int ret = 0;
58     ret = Findmaxsum(box,8,0,7);
59     printf("%d",ret);
60     return 0 ;
61  } 

遗留问题,此算法时间复杂度为 O(NlogN). 思考如何求得。

时间: 2024-10-10 20:52:42

分治法(求最大子序列和)的相关文章

分治法求最大子序列

给定一个序列,下标为 i, i+1, i+2, ...... , j,设 mid = (i+j)/2, 则最大子序列可能出现的地方有三个,mid的左边,mid的右边,或者在中间(包括mid).只要求出左边和右边的最大子序列(子问题),和边界上左边和右边最大子序列的和,找出三个子序列中最大的即可. #include <iostream> using namespace std; /*分治法解决最大子序列问题*/ int MaxSubSum(const int a[], int left, int

使用分治法求最大子序列之和

对于求最大子序列之和,对于我这样的菜鸟,首先想到的应该是最暴力的方法,就是将所有的子序列的和进行比较,然后出现最大值并返回答案.不过这也没啥意思,复杂度O(N2). 对这个问题,有一个相对复杂的O(NlogN)的解法,就是使用递归.其主要思想是:比较左.右.中间三部分的序列和的大小,因为中间部分是没办法分治的,只能在每一层递归函数空间里面进行,所以递归的部分为左.右,而且左右部分序列和有分别为次层递归的结果.递归的基本边界:左右为相同位置元素,即只有一个元素. 1 private static

《github一天一道算法题》:分治法求数组最大连续子序列和

看书.思考.写代码! /*************************************** * [email protected] * blog: http://blog.csdn.net/hustyangju * 题目:分治法求数组最大连续子序列和 * 思路:分解成子问题+合并答案 * 时间复杂度:O(n lgn) * 空间复杂度:O(1) ***************************************/ #include <iostream> using nam

分治法求众数问题 (配图)

分治法求众数问题 (配图) 采用分治法,以中间为界限, 先计算围绕中间这个数字的众数情况,然后左右分开递归计算结果,取最值即可. 左右递归计算的时候要先做判断,假如左边或是右边的个数都比已求的重数小,就没必要计算了,即使左边或是右边全部都是一样的,那么他的重数也是小于已求的,所以没必要进行运算,这一周在加深分治算法的学习,这题着实花了我不少时间. 具体代码: // 用分治法求众数 #include <iostream> #include <cstdio> using namespa

分治法求数组的最大值最小值

实现求数组的最大值最小值,蛮力法要容易的多.本着重在体验分治法的思想的原则: 1 int main(void) 2 { 3 void Maxmin(int a[],int low,int high,int maxmin[2]); 4 int a[10],maxmin[2]; 5 6 printf("Enter 10 integer numbers:\n"); 7 for(int i=0;i<10;i++) 8 scanf("%d",a+i); 9 10 Max

HDU ACM 1007 Quoit Design 分治法求最近点对

题意:给n个点的坐标,求距离最近的一对点之间距离的一半. 分析:分治法求最近点对. #include<iostream> #include<algorithm> #include<cmath> using namespace std; #define N 100005 double min(double a,double b) { return a<b?a:b; } struct POINT { double x,y; }; POINT point[N],*px[

分治法求逆序对数目

设A[1..n]是一个包含n个不同整数的数组.如果在i<j的情况下,有A[i]>A[j],则(i,j)就称为A中的一个逆序对(inversion). 给出一个算法,确定n个元素的任何排列中逆序对的书目.时间复杂度为o(nlgn). 分治法求解思路: 分解:将数组A[1..n]分为两个子序列A[1..p]和A[p+1,n],二分法将其分解.. 解决:根据归并排序的思想,在合并过程中,计算逆序对.假如两个子序列为X={4,5}和Y={2,3},则XY的逆序对为X中元素大于Y中元素的数目. 合并:对

分治法 求 逆序对数 的个数 时间复杂度为O(n*logn)

思路: 分治法 归并排序的过程中,有一步是从左右两个数组中,每次都取出小的那个元素放到tmp[]数组中 右边的数组其实就是原数组中位于右侧的元素.当不取左侧的元素而取右侧的元素时,说明左侧剩下的元素均比右侧的第一个元素大,即均能构成一个逆序对.假设现在左侧剩余n个元素,则逆序对数+n. 另外,如果当所有右侧的元素都取完,但是左侧仍然有元素剩余时,左侧剩余的元素已经在之前的运算中加到了逆序对中,不需要再添加一次 下面给出 归并排序 和 求逆序对数 两份代码: code1: 归并排序 #includ

算法笔记_065:分治法求逆序对(Java)

目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 分治法(归并排序)   1 问题描述 给定一个随机数数组,求取这个数组中的逆序对总个数.要求时间效率尽可能高. 那么,何为逆序对? 引用自百度百科: 设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同. 如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数. 例如,数组(3,1,4,5,

poj 3714 Raid 分治法求平面最近点对

题意: 给平面上的n个点,求两点间的最短距离. 分析: 分治法,保存点用vector会tle... 代码: //poj 3714 //sep9 #include <iostream> #include <algorithm> #include <cmath> using namespace std; const double INF=1e50; struct P { double x,y; int type; }p[240000],b[240000]; bool cmp