最大子列和問題

解法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;
}


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