48
这个题应该可以用递归写。但是通过观察可以发现规律,因为有正负数,把正负数分开放,再按绝对值从大到小排序。
然后取负数的话要取2,4,6,8.。。个,所以把排序后的两两相乘(1*2,3*4,5*6.。。),再分别讨论取1个相乘之后的数,2个,3个...,然后剩下的m-i*2个就全取正数。
不断地记录最大值。
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cstring> #include <algorithm> #include <cstdlib> #define FOR(i,x,n) for(int i=x;i<n;i++) #define FOR2(i, x, n) for(int i=int(x);i<int(n);i+=2) #define ll long long int #define INF 0x3f3f3f3f #define MOD 1000000007 #define MAX_N 50005 using namespace std; bool cmp(ll a,ll b){ return a>b; } int main() { //freopen("data.txt", "r", stdin); //freopen("data.out", "w", stdout); ll positiveNumber[30000]; ll negativeNumber[30000]; ll n,m; ll x=0,y=0; ll t;//临时 ll cou; scanf("%lld",&cou); while(cou--){ x=0,y=0; ll tt=-INF; scanf("%lld %lld",&n,&m); FOR(i,0,n){ scanf("%lld",&t); tt=max(tt,t); if(t>=0){ positiveNumber[x++]=t; }else{ negativeNumber[y++]=t; } } sort(positiveNumber,positiveNumber+x,cmp); sort(negativeNumber,negativeNumber+y); ll c=0; if(m==1){ printf("%d\n",tt); continue; } FOR2(i,0,y){ negativeNumber[c++]=negativeNumber[i]*negativeNumber[i+1]; } ll maxx=0; ll multi=1; FOR(i,0,m){ multi*=positiveNumber[i]; } maxx=max(maxx,multi); FOR(i,1,n/2){ multi=1; FOR(j,0,i){ multi*=negativeNumber[j]; } FOR(j,0,m-i*2){ multi*=positiveNumber[j]; } maxx=max(maxx,multi); } printf("%lld\n",maxx); } //fclose(stdin); //fclose(stdout); return 0; }
原文:http://www.cnblogs.com/TWS-YIFEI/p/6391170.html