藍橋杯 演算法提高 ADV-15 最大乘積
阿新 • • 發佈:2019-01-05
演算法提高 最大乘積
時間限制:1.0s 記憶體限制:512.0MB
問題描述
對於n個數,從中取出m個數,如何取使得這m個數的乘積最大呢?
輸入格式
第一行一個數表示資料組數
每組輸入資料共2行:
第1行給出總共的數字的個數n和要取的數的個數m,1<=n<=m<=15,
第2行依次給出這n個數,其中每個數字的範圍滿足:a[i]的絕對值小於等於4。
輸出格式
每組資料輸出1行,為最大的乘積。
樣例輸入
1
5 5
1 2 3 4 2
樣例輸出
48
分析:這個題不難,直接貪心就好了。值得注意的是,兩個負數的乘積
兩個正數乘積的情況,結果要取兩個負數的積。否則先取一個最大的正數即可。具體操作見註釋,程式碼如下:
#include <iostream> #include <algorithm> using namespace std; int map(int a, int b) { return a > b; } int main() { int num; int n, m; int *a; int l, r; int res; //第一行一個數表示資料組數 cin >> num; //每組輸入資料共2行: while(num--) { //第1行給出總共的數字的個數n和要取的數的個數m,1<=n<=m<=15, cin >> n >> m; a = new int[n]; //第2行依次給出這n個數,其中每個數字的範圍滿足:a[i]的絕對值小於等於4。 for(int j = 0; j < n; j++) cin >> a[j]; //為陣列從大到小排序 sort(a, a + n, map); //左右端指標l,r以及最終結果res的初始化 l = 0, r = n - 1, res = 1; //取m個數 while(m > 0) { if(m >= 2) { int left = a[l] * a[l+1]; int right = a[r] * a[r-1]; if(left <= right) //如果右端乘積比左端大,說明是兩個負數,取他們的積 { res *= right; r -= 2; m -= 2; } else //否則取最大的正數 { res *= a[l]; l++; m--; } } else //最後一個只能取較大的數 { res *= a[l]; l++; m--; } } cout << res << endl; //輸出結果 delete a; } return 0; }