算法提高 最大乘积
算法提高 最大乘积
时间限制:1.0s 内存限制:512.0MB
问题描述
对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢?
输入格式
第一行一个数表示数据组数
每组输入数据共2行:
第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15,
第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4。
每组输入数据共2行:
第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15,
第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4。
输出格式
每组数据输出1行,为最大的乘积。
样例输入
1
5 5
1 2 3 4 2
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; }