算法提高 最大乘积

 算法提高 最大乘积  
时间限制:1.0s   内存限制:512.0MB
    
问题描述
  对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢?
输入格式
  第一行一个数表示数据组数
  每组输入数据共2行:
  第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15,
  第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4。
输出格式
  每组数据输出1行,为最大的乘积。
样例输入
1
5 5
1 2 3 4 2
样例输出
48 
这个题应该可以用递归写。但是通过观察可以发现规律,因为有正负数,把正负数分开放,再按绝对值从大到小排序。
然后取负数的话要取2,4,6,8.。。个,所以把排序后的两两相乘(1*2,3*4,5*6.。。),再分别讨论取1个相乘之后的数,2个,3个...,然后剩下的m-i*2个就全取正数。
不断地记录最大值。
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#define FOR(i,x,n) for(int i=x;i<n;i++)
#define FOR2(i, x, n) for(int i=int(x);i<int(n);i+=2)
#define ll long long int
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define MAX_N 50005

using namespace std;

bool cmp(ll a,ll b){
    return a>b;
}

int main()
{
    //freopen("data.txt", "r", stdin);
    //freopen("data.out", "w", stdout);
    ll positiveNumber[30000];
    ll negativeNumber[30000];
    ll n,m;
    ll x=0,y=0;
    ll t;//临时
    ll cou;
    scanf("%lld",&cou);
    while(cou--){
        x=0,y=0;
        ll tt=-INF;
        scanf("%lld %lld",&n,&m);
        FOR(i,0,n){
            scanf("%lld",&t);
            tt=max(tt,t);
            if(t>=0){
                positiveNumber[x++]=t;
            }else{
                negativeNumber[y++]=t;
            }
        }
        sort(positiveNumber,positiveNumber+x,cmp);
        sort(negativeNumber,negativeNumber+y);
        ll c=0;
        if(m==1){
            printf("%d\n",tt);
            continue;
        }
        FOR2(i,0,y){
            negativeNumber[c++]=negativeNumber[i]*negativeNumber[i+1];
        }
        ll maxx=0;
        ll multi=1;
        FOR(i,0,m){
            multi*=positiveNumber[i];
        }
        maxx=max(maxx,multi);
        FOR(i,1,n/2){
            multi=1;
            FOR(j,0,i){
                multi*=negativeNumber[j];
            }
            FOR(j,0,m-i*2){
                multi*=positiveNumber[j];
            }
            maxx=max(maxx,multi);
        }
        printf("%lld\n",maxx);
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}

 

posted @ 2017-02-12 16:01  多一份不为什么的坚持  阅读(696)  评论(0编辑  收藏  举报