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;
}

 

 

posted @ 2018-09-12 17:10  一砂一极乐  阅读(272)  评论(0编辑  收藏  举报