乘积最大

乘积最大

给定 $N$ 个整数 $A_{1},A_{2},…A_{N}$。

请你从中选出 $K$ 个数,使其乘积最大。

请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 $1000000009$ 的余数。

注意,如果 $X<0$, 我们定义 $X$ 除以 $1000000009$ 的余数是负$\left( {−X} \right)$除以 $1000000009$ 的余数,即:$0 - \left( {\left( {0 - x} \right)\% 100000009} \right)$

输入格式

第一行包含两个整数 $N$ 和 $K$。

以下 $N$ 行每行一个整数 $A_{i}$。

输出格式

输出一个整数,表示答案。

数据范围

$1 \leq K \leq N \leq {10}^{5}$,
${−10}^{5} \leq A_{i} \leq {10}^{5}$

输入样例1:

5 3
-100000
-10000
2
100000
10000

输出样例1:

999100009

输入样例2:

5 3
-100000
-100000
-2
-100000
-100000

输出样例2:

-999999829

 

解题思路

  由于数中可能会有负数,为了尽可能得到正数,每次我们都成对选数。

  1. $k == n$,则全选。
  2. $k < n$:
    1. 如果$k$是偶数,结果必然可以取到非负,原因如下:
      1. 如果负数的个数是偶数个,那么我们每次都成对去选,必然可以保证选的负数是偶数个,从而保证答案可以是非负的。
      2. 如果负数的个数是奇数个,由于$k < n$,我们一定可以把其中一个负数剔除掉,不选这个负数,那么负数又变成偶数个,变成上一种情况,保证答案可以是非负的。
    2. 如果$k$是奇数:
      1. 如果全部数都是负数,结果必然小于$0$。
      2. 如果至少存在一个数是非负的,那么我们先选择其中一个非负的数,那么就变成了从$n - 1$个数中选$k - 1$个数,同时$k - 1$是偶数,又变成了上面第一类的情况,从而保证答案可以是非负的。

  AC代码如下:

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 
 9 const int N = 1e5 + 10, mod = 1e9 + 9;
10 
11 int a[N];
12 
13 int main() {
14     int n, m;
15     scanf("%d %d", &n, &m);
16     for (int i = 0; i < n; i++) {
17         scanf("%d", a + i);
18     }
19     
20     sort(a, a + n);
21     
22     int ret = 1, i = 0, j = n - 1, sign = 1;
23     if (m & 1) {        // 如果k是奇数
24         ret = a[j--];   // 先选择最右边的那个数
25         if (ret < 0) sign = -1; // 如果最右边的数是负数,意味着全部数都是负数
26         m--;
27     }
28     
29     while (m) {
30         LL left = (LL)a[i] * a[i + 1], right = (LL)a[j] * a[j - 1]; // 每次成对选数
31         
32         // 选择最左最右乘积最大的一对数。其中如果所有数是负数,那么应该选择最右边的那对
33         if (left * sign > right * sign) {
34             ret = left % mod * ret % mod;
35             i += 2;
36         }
37         else {
38             ret = right % mod * ret % mod;
39             j -= 2;
40         }
41         m -= 2;
42     }
43     
44     printf("%d", ret);
45     
46     return 0;
47 }

 

参考资料

  AcWing 1239. 乘积最大(蓝桥杯C++ AB组辅导课):https://www.acwing.com/video/735/

posted @ 2022-03-03 12:29  onlyblues  阅读(120)  评论(0编辑  收藏  举报
Web Analytics