假设数组为a[],直接利用动归来求解,考虑到可能存在负数的情况,我们用Max来表示以a结尾的最大连续子串的乘积值,用Min表示以a结尾的最小的子串的乘积值,那么状态转移方程为:
Max=max{a, Max[i-1]*a, Min[i-1]*a};
Min=min{a, Max[i-1]*a, Min[i-1]*a};
初始状态为Max[1]=Min[1]=a[1]。
代码很简单:
double func(double *a,const int n)
{
double *maxA = new double[n];
double *minA = new double[n];
maxA[0] = minA[0] =a[0];
double value = maxA[0];
for(int i = 1 ; i < n ; ++i)
{
maxA[i] = max(max(a[i],maxA[i-1]*a[i]),minA[i-1]*a[i]);
minA[i] = min(min(a[i],maxA[i-1]*a[i]),minA[i-1]*a[i]);
value=max(value,maxA[i]);
}
return value;
}
此外,此题还有另外的一个变种形式,即给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组,并写出算法的时间复杂度。
实现方法就是空间换时间,定义三个数据p[], s[], t[], 其中s[i]中存储数组前i个元素的乘积, t[i]存储后N-i个元素的乘积,则可得p[i]=s[i-1]*t[i+1];