乘积最大
乘积最大
给定 个整数 。
请你从中选出 个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 的余数。
注意,如果 , 我们定义 除以 的余数是负除以 的余数,即:
输入格式
第一行包含两个整数 和 。
以下 行每行一个整数 。
输出格式
输出一个整数,表示答案。
数据范围
,
输入样例1:
5 3 -100000 -10000 2 100000 10000
输出样例1:
999100009
输入样例2:
5 3 -100000 -100000 -2 -100000 -100000
输出样例2:
-999999829
解题思路
由于数中可能会有负数,为了尽可能得到正数,每次我们都成对选数。
- ,则全选。
- :
- 如果是偶数,结果必然可以取到非负,原因如下:
- 如果负数的个数是偶数个,那么我们每次都成对去选,必然可以保证选的负数是偶数个,从而保证答案可以是非负的。
- 如果负数的个数是奇数个,由于,我们一定可以把其中一个负数剔除掉,不选这个负数,那么负数又变成偶数个,变成上一种情况,保证答案可以是非负的。
- 如果是奇数:
- 如果全部数都是负数,结果必然小于。
- 如果至少存在一个数是非负的,那么我们先选择其中一个非负的数,那么就变成了从个数中选个数,同时是偶数,又变成了上面第一类的情况,从而保证答案可以是非负的。
- 如果是偶数,结果必然可以取到非负,原因如下:
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/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/15959041.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探