2.13子数组最大乘积

问题:
给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组。

解法一:
采用空间换时间的策略,用两个数组分别记录原整数数组前缀与后缀的叠乘积(前缀s[i]=),再以间隔1个数的方式将这两个数组乘起来就得到所有n-1个数的乘积数组(具体看代码)。
[cpp]
#include <iostream> 
#include <algorithm> 
using namespace std; 
 
#define MAXN 1003 
long long A[MAXN]; 
 
long long s[MAXN]; 
long long t[MAXN]; 
 
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]; 
    // 计算出n-1个n-1数连乘 
    for (i=0; i<=n-1; i++) 
        s[i] = s[i]*t[i+2]; 
    long long maximum = s[0]; 
    // 获取其中的最大值 
    for (i=1; i<=n-1; i++) 
        maximum = max(maximum, s[i]); 
    cout << maximum << endl; 

解法二:
对N个数的乘积进行分析,用启发式的方式得到在满足乘积最大情况下要删去那个数。
[cpp]
#include <iostream   > 
#include <algorithm> 
using namespace std; 
 
#define MAXN 1003 
long long A[MAXN]; 
 
#define INF 0x7fffffff 
 
int main() 

    int n, i, j; 
    cin >> n; 
    for (i=1; i<=n; i++) 
        cin >> A[i]; 
    // 从前往后用叠乘法 
    long long P = 1; 
    for (i=1; i<=n; i++) 
        P*=A[i]; 
    if (P==0) 
    { 
        for (j=1; j<=n && A[j]; j++); 
        long 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 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 long Q = 1; 
            for (i=1; i<=n; i++) 
                if (i!=j) Q *= A[i]; 
            cout << Q << "," << j << endl; 
        } 
        else 
        { 
            long long minNeg = A[1]; 
            for (i=2; i<=n; i++) 
                if (A[i] < minNeg) 
                { 
                    minNeg = A[i]; 
                    j = i; 
                } 
            long 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 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 long Q = 1; 
        for (i=1; i<=n; i++) 
            if (i!=j) Q *= A[i]; 
        cout << Q << "," << j << endl; 
    } 

 作者:li

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值