选刚好k个。。 算记录吧。。也是看别人的题解的。。下面有分析。
总体思路就是要拿偶数个 相乘绝对值较大的。。这就是为什么两个两个拿
如果不是偶数个。那么就给他转换成偶数个的问题。。
void solve() {
cin >> n >> k;
int a[n];
for (int &x : a)
cin >> x;
sort(a, a + n);
int f = 1, l = 0, r = n - 1;
Z ans = 1;
if (k & 1) {
ans = a[n - 1];
if (a[r] < 0)f = -1;//如果没有正数的时候才需要取绝对值较小的
r--; k--;
}
while (k) {
int x = a[l + 1] * a[l], y = a[r] * a[r - 1];
if (x * f > y * f)
ans *= x, l += 2;
else
ans *= y, r -= 2;
k -= 2;
}
cout << ans;
};
// 题意:求从n个数选出k个数的乘积最大值结果%1e9+7。
// 思路:对于多个数的乘积想要结果最大,在满足绝对值最大的情况下要满足包含偶数个负数‼️。
// 情况1:对于所选的数是奇数时,首先就取一个最大正数,接下来就是俩个正数积和俩个负数积取最大。
// 特殊情况2:当总正数数量为0,且选择数量为奇数时结果一定为负,这时要想结果最大就要取k个绝对值最小的数。
// 然后就可以愉快的ac了。(细节看代码)
// 原文链接:https://blog.csdn.net/acmzhou/article/details/107154462
// 剩下疑问就是为什么两个两个拿 。然后为什么是相邻的????还是绝对值最大化吧。。
// 写个例子 -2 1 2 3 。。当左边拿到 -2*1 的时候肯定是不拿的 或者说最后拿。。所以这个策略是对的。。
//实际上分类。还是可以理解这个策略的。。
// 如果奇数 。。1最大那个正数 肯定必拿的。。2 。如果最大的都是负数。。那么也要拿他。。因为他是绝对值最小的。。
// 我们要找的就是绝对值的最大化。。 两个两个拿保证是正数。。
实际上这些问题都不是问题。。