最大连续子序列乘积

问题描述

给定一个整数序列(可能有正数,0和负数),求它的一个最大连续子序列乘积。比如给定数组a={3, -4, -5, 6, -2},则最大连续子序列乘积为720,即3*(-4)*(-5)*6=720。


分析

求最大连续子序列乘积与最大连续子序列和问题有所不同,因为其中有正有负还有可能有0。

假设数组为a[],直接利用动归来求解,考虑到可能存在负数的情况,我们用Max[i]来表示以a[i]结尾的最大连续子序列的乘积值,用Min[i]表示以a[i]结尾的最小的连续子序列的乘积值,那么状态转移方程为:

       Max[i]=max{a[i], Max[i-1]*a[i], Min[i-1]*a[i]};
       Min[i]=min{a[i], Max[i-1]*a[i], Min[i-1]*a[i]};
初始状态为Max[0]=Min[0]=a[0]。代码如下:
#include"iostream"    
using namespace std;    

int max3(int a,int b,int c)
{
	int t = a>b?a:b;
	return t>c?t:c;
}

int min3(int a,int b,int c)
{
	int t = a<b?a:b;
	return t<c?t:c;
}

int max_multiple(int *a,int n)  
{  
	int *Min = new int[n]();  
	int *Max = new int[n]();  
	Min[0]= Max[0] = a[0];   
	int max = Max[0];  
	for(int i=1; i<n; i++){  
		Max[i] = max3(Max[i-1]*a[i],Min[i-1]*a[i],a[i]); //求三个数中最大值  
		Min[i] = min3(Max[i-1]*a[i],Min[i-1]*a[i],a[i]); //求三个数中最小值  
		if(max < Max[i])  
			max = Max[i];  
	}  
	//内存释放  
	delete [] Max;  
	delete [] Min;  
	return max;  
}  

//不保存中间变量的实现方法
int max_multiple_2(int *a,int n)  
{  
	int minsofar, maxsofar, max;  
	max = minsofar = maxsofar = a[0];  
	for(int i=1;i<n;i++){  
		int maxhere = max3(maxsofar*a[i], minsofar*a[i], a[i]);  
		int minhere = min3(maxsofar*a[i], minsofar*a[i], a[i]);  
		maxsofar = maxhere;
		minsofar = minhere;  
		if(max < maxsofar)  
			max = maxsofar;  
	}  
	return max;  
}  

int main()
{
	int a[]={3, -4, 0, 6, -2};
	cout<<max_multiple_2(a,5)<<endl;
	system("pause");
	return 0;
}

你可能感兴趣的:(最大连续乘积)