算法提高 最大乘积
时间限制: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
分析:这个题不难,直接贪心就好了。值得注意的是,两个负数的乘积
两个正数乘积的情况,结果要取两个负数的积。否则先取一个最大的正数即可。具体操作见注释,代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
int map(int a, int b)
{
return a > b;
}
int main()
{
int num;
int n, m;
int *a;
int l, r;
int res;
//第一行一个数表示数据组数
cin >> num;
//每组输入数据共2行:
while(num--)
{
//第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15,
cin >> n >> m;
a = new int[n];
//第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4。
for(int j = 0; j < n; j++) cin >> a[j];
//为数组从大到小排序
sort(a, a + n, map);
//左右端指针l,r以及最终结果res的初始化
l = 0, r = n - 1, res = 1;
//取m个数
while(m > 0)
{
if(m >= 2)
{
int left = a[l] * a[l+1];
int right = a[r] * a[r-1];
if(left <= right) //如果右端乘积比左端大,说明是两个负数,取他们的积
{
res *= right;
r -= 2;
m -= 2;
}
else //否则取最大的正数
{
res *= a[l];
l++;
m--;
}
}
else //最后一个只能取较大的数
{
res *= a[l];
l++;
m--;
}
}
cout << res << endl; //输出结果
delete a;
}
return 0;
}