最大乘积(Maximum Product,Uva 11059)

原题摘录

输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列.如果这个最大的乘积不是正数,输出0.(1<=n<=18,-10<=Si<=10).

样例输入

3

2 4 -3

5

2 5 -1 2 -1

样例输出

8

20

分析

连续子序列有两个要素:起点和终点,因此只需枚举起点和终点即可.由于每个元素的绝对值不超过10,且不超过18个元素,最大乘积不超过10^18,可以用long long存储.

两种解决方法:暴力求解和动态规划

AC代码(注释)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;

int  n;

int maxProduct(int nums[]) {
        //思路一:暴力求解
        //遍历数组元素,每个元素维护一个变量,代表当前的乘积
        //全局变量max,最大的乘积
        int max = nums[0];
        
        for(int i = 0; i < n; i++) {
            int mul = 1;
            
            for(int j = i; j < n; j++) {
                mul *= nums[j];
                
                if(mul > max) {//直接在循环内部作比较,而不用算出所有再比较 
                    max = mul;//更新最大值 
                }
            }
        }
        
        return max;
}
//int maxProduct(int nums[],int len) { 
        //思路二:动态规划
        //遍历数组,每个元素对应以该元素为结尾的子序列的最大值和最小值两个变量,更新乘积最大值
//        int posmax = nums[0], negmin = nums[0], maxn = nums[0];//阳阴 
//        
//        for(int i = 1; i < len; i++) {
//            int pre_posmax = posmax;
//            int pre_negmin = negmin;
//            
//            posmax = max(nums[i], max(nums[i]*pre_posmax, nums[i]*pre_negmin));
//            negmin = min(nums[i], min(nums[i]*pre_posmax, nums[i]*pre_negmin));
//          
//            if(max(posmax, negmin) > maxn) {
//                maxn = max(posmax, negmin);
//            }          
//        }   
//        return maxn;  
    
//}


int main(int argc, char** argv)
{
    
    while(cin>>n&&n){
    int  a[20],i;
	long  answer;
	
    for(i=0;i<=n-1;i++)
    cin>>a[i];
    
    answer=maxProduct(a); //思路一
    //answer=maxProduct(a,i); //思路二
	if(answer<0) cout<<"0"<<endl;
	else cout<<answer<<endl;
    }
	return 0;
} 
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值