最大子列和问题

解法1:

直接枚举所有情况暴力求解问题 O (n^3)

解法2:

在解法1的基础上改善了局部求和方法,使用递推和式代替每次累加求和 O (n^2)

解法3:

采用分治法求解,将数列递归地一分为二,最大子列和就等于左边的最大子列和与右边的最大子列和与跨越中线的最大子列和的最大值。 O (n logN)

解法4:

采用在线扫描方法,从起点开始往终点扫描,记录当前的子列和,如果为负数则舍弃之并将当前和置0,并更新现发现的当前最大子列和。 O (n)



#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#define MAX(a,b) (a)>(b)?(a):(b)
using namespace std;
int a(int *str, int x, int y){//	暴力求解法	array str,   [x,y)
	if (x == y)						//异常处理
		return -1;
	int max = str[x],curSum;
	for (int i = x; i < y; i++){
		for (int j = i; j < y; j++){
			curSum = 0;
			for (int k = i; k <= j; k++){			//calculate the current sum from i to j
				curSum += str[k];
			}
			if (max < curSum){
				max = curSum;
			}
		}
	}
	return max;
}

int b(int *str, int x, int y){//		暴力求解法的优化
	if (x == y)						//异常处理
		return -1;
	int max = str[x], curSum;
	for (int i = x; i < y; i++){
		curSum = 0;					//	和式由递推关系获得
		for (int j = i; j < y; j++){
			curSum += str[j];
			if (max < curSum){
				max = curSum;
			}
		}
	}
	return max;
}

int c(int *str, int x, int y){<span style="white-space:pre">					</span>// <span style="white-space:pre">	</span>分治法
	if (x == y)						//异常处理
		return -1;
	if (y - x == 1)					// 如果只有一个元素,则直接返回
		return str[x];
	int mid = x + (y - x) / 2;		//划分成两个子区间
	int max = MAX(c(str, x, mid), c(str, mid, y));//	递归求解每个区间的最大子列和
	int left, right, curSum, maxLeft = str[mid-1], maxRight = str[mid];	//求解中间部分的最大子列和
	for (left = mid-1, curSum = 0; left >= x; left--){		
		curSum += str[left];
		if (curSum > maxLeft){
			maxLeft = curSum;
		}
	}
	for (right = mid, curSum = 0; right < y; right++){
		curSum += str[right];
		if (curSum>maxRight){
			maxRight = curSum;
		}
	}
	return MAX(max, maxLeft + maxRight);
}

int d(int *str, int x, int y){		//在线扫描法
	if (x == y)						//异常处理
		return -1;
	int curSum =0, max = str[x];
	for (int i = x; i < y; i++){
		curSum += str[i];
		if (curSum>max){
			max = curSum;	//更新最大和
		}
		if (curSum < 0){
			curSum = 0;		//如果为负数则舍弃之并将当前和置0,因为当前子列和为负只能使之后的子列和变小
		}
	}
	return max;
}

int main()
{
	int array[] = {4,-3,5,-2,-1,2,6,-2};
	cout << "暴力求解	:"<<a(array,0,8)<<endl;
	cout << "优化后的暴力求解		:"<<b(array, 0, 8) << endl;
	cout << "分治求解	:"<<c(array, 0, 8)<<endl;
	cout << "最优的在线处理	:"<<d(array, 0, 8) << endl;
	system("pause");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章