1. 程式人生 > >最大欄位和的3中解法

最大欄位和的3中解法

問題描述:

    給定n個整數,組成序列a[1], a[2], a[3], ... a[n],求形如a[i]+a[i+1]+...+a[j]的欄位和的最大值。

// 最大子段求和,窮舉法,複雜度O(n^2)
// 輸入引數:a[]儲存資料,其中a[0]儲存資料個數
// 返回值:返回最大子段的和值
long MaxSum0(int a[])
{
	int i, j;	// 在[i,j]區間求欄位和
	int sum = 0;
	long max = -200000L;

	// 三重迴圈:第一重是左邊界迴圈,第二重是右邊界迴圈,第三重是累加迴圈
	for(i = 1; i <= a[0]; i ++)
	{
		sum = 0;
		for(j = i; j <= a[0]; j ++)
		{
			sum += a[j];
			if(max < sum)
				max = sum;
		}
	}
	return max;
}

// 最大子段求和,分治法,複雜度O(nlog(n))
// 將a[1...n]分為兩部分a[1...n/2]和a[n/2+1...n],則a[1...n]的最大子段會有三種情況:
// (1) a[1...n]的最大子段會是a[1...n/2]的最大子段
// (2) a[1...n]的最大子段會是a[n/2+1...n]的最大子段
// (3) a[1...n]的最大子段會是a[i...j],其中1<=i<=n/2, n/2+1<=j<=n
// T(n) = 2T(n/2) + O(n)
// T(n) = O(nlog(n))
// 輸入引數:a[]儲存資料,其中a[0]儲存資料個數;l為子段的左邊界;r為子段的右邊界
// 返回值:返回最大子段的和值
long MaxSum1(int a[], int l, int r)
{
	int center = (l+r)/2;					// 子段的中間索引
	long lMax = 0, rMax = 0;				// 左右區間的最大子段和值
	long sum0, sum1, max0, max1, mMax;		// 中部區間的最大子段和值
	long max = 0;            
	if(l == r)			                    // 如果是一個數,那最大子段和就是本身
		return a[l];
	else
	{
		lMax = MaxSum1(a, l, center);		// 迭代呼叫MaxSum1求取左區間的最大和值
		rMax = MaxSum1(a, center+1, r);     // 迭代呼叫MaxSum1求取右區間的最大和值
		
		// 求取中部區間的最大和值
		// 從center向左求最大和值
		max0 = -20000L;
		sum0 = 0;
		for(int i = center; i >= l; i --)
		{
			sum0 += a[i];
			if(max0 < sum0)
				max0 = sum0;
		}
		// 從center+1向右求最大和值
		max1 = -20000L;
		sum1 = 0;
		for(int i = center+1; i <= r; i ++)
		{
			sum1 += a[i];
			if(max1 < sum1)
				max1 = sum1;
		}

		mMax = max0 + max1;					// 中部區間的最大和值

		max = mMax;
		
		if(lMax > max)
			max = lMax;
		if(rMax > max)
			max = rMax;

		return max;
	}
}

// 最大子段求和,動態規劃法,複雜度O(n)
// b[j] = a[i] + ... + a[j], 1<=i<=j, 1<=j<=n, 則最大子段和即是max b[j], 1<=j<=n
// 若b[j-1]<=0, 則b[j] = a[j]; 若b[j-1]>0, 則b[j] = b[j-1] + a[j]
// T(n) = O(n)
// 輸入引數:a[]儲存資料,其中a[0]儲存資料個數
// 返回值:返回最大子段的和值
long MaxSum2(int a[])
{
	int max;
	int b;

	max = b = a[1];
	for(int i = 2; i <= a[0]; i ++)
	{
		if(b <= 0)
			b = a[i];
		else
			b += a[i];
		if(max < b)
			max = b;
	}

	return max;
}


相關推薦

關於的若干解法優化

最大欄位和是常見的一個入門演算法問題,根據演算法的優化程度,這裡分為了四種方法: 第一種:複雜度為O(N ^ 2),兩個用於語句巢狀 int summax_1(int *a,int tem) { int temp=0,temp_maxi=0,temp_maxj=

3解法

問題描述:     給定n個整數,組成序列a[1], a[2], a[3], ... a[n],求形如a[i]+a[i+1]+...+a[j]的欄位和的最大值。 // 最大子段求和,窮舉法,複雜度O(n^2) // 輸入引數:a[]儲存資料,其中a[0]儲存資料個數 //

分治法 解決問題

分治法求解最大欄位和問題 1 問題描述   給定由n個整數(可能由負數)組成的序列(a1, a2,...,an),最大欄位和問題求 該序列中連續子段和的最大值,並找出這個連續子段。 2 使用python程式設計解決,具體程式碼如下   # 求出最大子段和, 以及最大子段和 對應的位置

動態規劃

最大子段和 給定由n個整數(可能有負整數)組成的序列(a1,a2,…,an),最大子段和問題要求該序列形如 的最大值(1<=i<=j<=n),當序列中所有整數均為負整數時,其最大子段和為0。 #include<stdio.h> #include<

演算法 |

         #include <stdio.h> int a[100001],dp[100001]; int main() { int T,n; while(~scanf("%d",&n)) {

HDU 1231 簡單DP之

原題地址:http://acm.hdu.edu.cn/showproblem.php?pid=1231 演算法核心: 動態規劃, 陣列為vec[]vec[],設dp[i]dp[i] 是以vec[i]

演算法優化:,雙指標遍歷(n^2),分治法(nlogn),動態規劃(n)

最大欄位和,有點類似與最長公共子序列,這裡是求連續一段求和最大的一段,比如[-2,11,-4,-4,13,-5,-2]最大求和的連續一段為11,-4,-4,13,和為16. 最基本的雙針模型遍歷,兩個指標,分別代表最大和序列的起始和終止,演算法時間複雜度O(n^2) # 以下演算法時

POJ 1050 To the Max 大子矩陣(二維的

傳送門: To the Max Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 52306 Accepted: 27646 Description Given a two-dimensional array of positive

poj1050及其衍生

每天做poj都會感覺到自己的收穫,今天做的是poj1050,以前沒接觸這些演算法類的東西,也就在資料結構課上水過兩把,所以每天接觸到這些新的東西覺得挺有意思,也確實感覺自己收穫了不少。 poj1050是一個欄位和的題,什麼是欄位和以及他的具體實現我是在這篇部落格上學到的,點

【演算法設計與分析】6、

/** * 書本:《演算法分析與設計》 * 功能:若給定n個整陣列成的序列a1, a2, a3, ......an, 求該序列形如ai+a(i+1)+......+an的最大值 * 檔案:MaxSum.cpp * 時間:2014年11月30日17:37:26 * 作者:cu

LeetCode——第53題:

題目: 給定一個整數陣列 nums ,找到一個具有最大和的連續子陣列(子陣列最少包含一個元素),返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6

——動態規劃

最大欄位和,常規解法有四種,分別是: 1、三重for迴圈; 2、兩重for迴圈; 3、分治解法; 4、動態規劃; 從時間複雜度的角度講,動態規劃是最優演算法,故對其簡單介紹: #include<iostream> using namespace std;

求陣列簡潔有效的演算法

直接上程式碼:public static int max(int[] a){ int max = 0;int zmax = 0; for (int i = 0;i<a.length;i++){ zmax += a[

動態規劃:問題

import java.util.Scanner; /* * 最大子段和問題,-2 11 -4 13 -5 -2中最大的子段和 */ public class MaxSum { publi

衝出暴力列舉

這篇解題報告是對我最近一些題的總結,裡面的程式碼都是我解題,優化,再優化的過程的記錄,記錄了自己對演算法的完善與優化思路,還有對程式設計哲學的理解:do it,do it well。 很感謝孫老師您,讓自己可以找到利用計算機作比只是單純玩遊戲更有意義又更有趣的事

基礎演算法--B

Description Given a sequencea[1],a[2],a[3]......a[n], your job is to calculate the max sum of asub-sequence. For example, given (6,-1,5,4

問題(常規法,分治法,動態規劃法)

演算法設計與分析-----求最大欄位和問題    問題描述:給定由n個整陣列成的序列(a1,a2,a3......,an),求該序列的子段的最大值. 常規法: 從a1開始,求出以a1開頭的子序列最大的和為sum,依次從a2開始,在sum等於以a1開頭的基礎上,與以

蠻力、分治、動態規劃求解問題(aardio)

最近的演算法課上要求做的一個實驗是分別用蠻力、分治、動態規劃求解最大欄位和問題。 以下是相關程式碼: 陣列求和程式段: var getsum = function(tab,frist,l

Maximum sum【變式】

【題目描述】 對於給定的整數序列A={a1,a2,…,an}A={a1,a2,…,an},找出兩個不重合連續子段,使得兩子段中所有數字的和最大。我們如下定義函式 d(A): 我們的目標就是求出d(A)。 【輸入】 第一行是一個整數T(≤30),代表一

@column 瞬時

大欄位     @Lob //對應Blob欄位型別        @Column(name = "PHOTO")        private Serializable photo;        @Lob //對應Clob欄位型別        @Column(name