YTU OJ.最大乘积
问题 F: 最大乘积
时间限制: 1 Sec 内存限制: 128 MB
提交: 292 解决: 39
[提交][状态][讨论版][命题人:acm4302]
题目描述
对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢?
输入
第一行一个数 代表数据组数
每组数据共两行
第一行两个正整数n、m, n,m<=20
第二行给出n个整数,其中每个数的绝对值小于4
输出
每组数据输出1行,为最大的乘积
样例输入
1 5 5 1 2 3 4 2
样例输出
48
分析:看到题的第一思路,建立两个数组a和b,正数存在a中,负数存在b中。
正数数组降序排列,负数数组升序排列。
当m>=2时,判断负数数组前两项乘积和正数数组前两项乘积的大小,选择大的。
m=1时单独考虑,选择当前没被选择的最大正数即可,其实这个地方就已经暴露问题了。
若是当前剩余的没有正数了,那所得的答案乘以一个负数,不可能是最大的了.......
重新思考,经过几次实验,问题最大的一组测试数据为1
5 3 -9 -8 -7 -4 -5
也就是输入全为负数且需要取奇数个的时候,那么特殊的优先考虑即可。
最后发现其实用一个数组存数据排序即可。
AC代码:
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define maxx 100
int a[maxx];
int flag;//标记是否存在正数
int cmp(int a,int b) {
return a>b;
}
int main() {
int t;
cin>>t;
while(t--) {
memset(a,0,sizeof(a));
flag=0;
int m,n;
cin>>n>>m;
for(int i=0; i<n; i++)
cin>>a[i];
sort(a,a+n,cmp);
if(a[0]>0)
flag=1;
long long sum=1;
int i=0,j=0,sum1,sum2;
if(flag) {
while(m) {
sum1=a[i]*a[i+1];//最大两正数
sum2=a[n-j-1]*a[n-j-2];//负数
if(sum2>=sum1&&m>=2) {
sum*=sum2;
j+=2;
m-=2;
} else {
sum*=a[i];
i++;
m--;
}
}
} else {
for(int i=0; i<m; i++)
sum*=a[i];
}
cout<<sum<<endl;
}
return 0;
}