“==============================================”一下的文章是错误的,因为乘积和求和不同,求和过程中正负属性会更改,而乘积不会。所以对于{-10,-10,1}这样的例子,那个算法是错误的。在网上看到一个DP算法,实现了一下。如下:
假设b[i]以a[i]结尾的最大连续子串乘积,d[i]为最小。则
b[0]=d[0]=a[0]
b[i] = max{b[i-1]*a[i], d[i-1]*a[i], a[i]};
d[i] = min{b[i-1]*a[i], d[i-1]*a[i], a[i]};
而整个问题的解就是max{b[i]}
#define __max__(a,b) ((a)>(b)?(a):(b))
#define __min__(a,b) ((a)<(b)?(a):(b))
double maxmulti2(int *p, int len)
{
double maxend, minend, maxres;
maxend = minend = maxres = *p;
for (int i = 1; i < len; ++i)
{
double end1 = maxend* *(p + i);
double end2 = minend* *(p + i);
maxend = __max__(__max__(end1, end2), *(p + i));
minend = __min__(__min__(end1, end2), *(p + i));
maxres = __max__(maxend, maxres);
}
return maxres;
}
==============================================
和数组子串的最大和 类似,数组子串的最大乘积也有两种求值方法。
对应的,之前的判断和改为判断积;之前的跟‘0’比较变成跟‘1’比较(若B>1,则AB比A大,否则比A小),对应代码为:
#include <iostream>
using namespace std;
double d[7];
double End[7];
double maxsub(double *p, int len)
{
if (p == NULL || len <= 0)
return -1;
d[0] = *p;
double sum, tmpsum;
sum = tmpsum = p[0];
for (int i = 1; i < len; ++i)
{
if (tmpsum>1)
tmpsum *= (*(p + i));
else
tmpsum = (*(p + i));
if (tmpsum > sum)
sum = tmpsum;
}
return sum;
}
double max(double a, double b)
{
return a > b ? a : b;
}
double maxsub2(double *p, int len)
{
if (p == NULL || len <= 0)
return -1;
d[0] = End[0] = *p;
for (int i = 1; i < len; ++i)
{
End[i] = max(End[i - 1] * p[i], p[i]);
d[i] = max(End[i], d[i - 1]);
}
return d[len - 1];
}
int main()
{
double a[7] = { -2.5, 4, 0, 3, 0.5, 8, -1 };
cout << maxsub(a, sizeof(a) / sizeof(double)) << endl;
cout << maxsub2(a, sizeof(a) / sizeof(double)) << endl;
system("pause");
return 0;
}