地址:http://codeforces.com/contest/1406/problem/B
题意:
给出n个数,找出5个数,使得乘积最大化。
解析:
5个数,分情况:
负 正
0 5
1 4
2 3
3 2
4 1
5 0
可以发现,对于负数个数为1,3的时候,这个时候结果是负数
假设这个时候n==5,那么就是从头乘到底
假设n>5,那么多出来那个数,要么是正数,要么是负数,要么是0。一定有办法把结果变成0或正数,所以可以把它们归到其他类里。
所以对于n>5的时候,负数只能取0,2,4。发现这些情况中,最优解就是从排好序的数组中首尾取5个。
所以可以枚举首部取的下标i,这里规定,i=1,首部取了0个,i=2,首部取了1个,i本身不取,所以i要枚举到6
思维过程:
枚举->发现无效组合->转化为求首尾取5个的最大乘积
代码:
#include<bits/stdc++.h> #include<map> #include<iostream> #include<cstring> #include<cmath> using namespace std; typedef long long ll; const int maxn=1e5+10; const int maxn2=1e9+10; const int mod=1e9+10; int a[maxn]; struct node { int x1,y1,x2,y2; }st[maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; ll maxx=-1e18; sort(a+1,a+1+n); for(int i=1;i<=6;i++) { ll md=1; for(int j=1;j<i;j++) md*=a[j]; for(int j=n;j>=n+i-5;j--) md*=a[j]; // cout<<i<<" "<<md<<endl; maxx=max(maxx,md); } cout<<maxx<<endl; } }