编程之美—-子数组的最大乘积
问题:
给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组。
方法一:
采用空间换时间的策略,用两个数组分别记录原整数数组前缀与后缀的叠乘积(前缀s[i]=A[i]*s[i-1],后缀t[i]=A[i]*t[i+1]),再以间隔1个数的方式将这两个数组乘起来就得到所有n-1个数的乘积数组.
代码为:
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1003
long A[MAXN];
long s[MAXN];
long t[MAXN];
int max(int a,int b)
{
if(a>b)
return a;
else
return b;
}
int main()
{
int n,i;
cin>>n;
for(i=1;i<=n;i++)
cin>>A[i];
s[0]=1;
for(i=1;i<n;i++)
s[i]=A[i]*s[i-1];
t[n+1]=1;
for(i=n;i>1;i–)
t[i]=A[i]*t[i+1];
for(i=0;i<=n-1;i++)
s[i]=s[i]*t[i+2];
long maximum=s[0];
for(i=1;i<=n-1;i++)
maximum=max(maximum,s[i]);
cout<<maximum<<endl;
}
方法二:
对N个数的乘积进行分析,用启发式的方式得到在满足乘积最大情况下要删去那个数。
代码为:
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1003
long A[MAXN];
int main()
{
int n,i,j;
cin>>n;
for(i=1;i<=n;i++)
cin>>A[i];
long P=1;
for(i=1;i<=n;i++)
P*=A[i];
if(P==0)
{
for(j=1;j<=n &&A[j];j++)
long Q=1;
for(i=1;i<=n;i++)
{
if(i!=j) Q*=A[i];
}
if(Q>=0)
cout<<Q<<“,”<<j<<endl;
else
cout<<“0″<<endl;
}
else if(P>0)
{
for(i=1;i<=n&&A[i]<0;i++)
if(i<=n)
{
long minPos=A[i];
j=i;
for(i=i+1;i<=n;i++)
{
if(A[i]>0&&A[i]<minPos)
{
minPos=A[i];
j=i;
}
}
long Q=1;
for(i=1;i<=n;i++)
{
if(i!=j) Q*=A[i];
}
cout<<A<<“,”<<j<<endl;
}
else
{
long minNeg=A[1];
for(i=2;i<=n;i++)
{
if(A[i]<minNeg)
{
minNeg=A[i];
j=i;
}
}
long Q=1;
for(i=1;i<=n;i++)
{
if(i!=j) Q*=A[i];
}
cout<<Q<<“,”<<j<<endl;
}
}
else
{
for(i=1;i<=n&&A[i]>0;i++);
long maxNeg=A[i];
j=i;
for(i=i+1;i<=n;i++)
{
if(A[i]<0&&A[i]>maxNeg)
{
maxNeg=A[i];
j=i;
}
}
long Q=1;
for(i=1;i<=n;i++)
{
if(i!=j) Q*=A[i];
}
cout<<Q<<“,”<<j<<endl;
}
return 0;
}
拓展题:给定一个整型数足a,求出最大连续子段的乘积,比如 1, 2, -8, 12, 7则输出12 * 7 = 84.
代码为:
#include <iostream>
using namespace std;
// 子数组的最大乘积
int MaxProduct(int *a, int n)
{
int maxProduct = 1; // max positive product at current position
int minProduct = 1; // min negative product at current position
int r = 1; // result, max multiplication totally
for (int i = 0; i < n; i++)
{
if (a[i] > 0)
{
maxProduct *= a[i];
minProduct = min(minProduct * a[i], 1);
}
else if (a[i] == 0)
{
maxProduct = 1;
minProduct = 1;
}
else // a[i] < 0
{
int temp = maxProduct;
maxProduct = max(minProduct * a[i], 1);
minProduct = temp * a[i];
}
r = max(r, maxProduct);
}
return r;
}
int main(int argc, char* argv[])
{
int a[]={1, -2, -3,0,5};
int result = MaxProduct(a,5);
cout<<result<<endl;
system(“pause”);
return 0;
}