「一本通 1.1 練習 1」數列極差
阿新 • • 發佈:2018-12-25
out main c++ href names 思路 結果 ++ air
題目傳送門
解題思路
這題也是典型的貪心算法題。
對於這個問題 先通過實例來認識問題所描述的計算過程。
令\(N=3\),取數列\(3,5,7\)
可能有下面三種情況
\((3×5+1)×7+1=113\)
\((3×7+1)×5+1=111\)
\((5×7+1)×3+1=109\)?
由此可見先運算小數據的到的是最大值,先運算大數據得到的是最小值。?
故針對此問題可采用貪心算法,下面驗證其合理性:
不妨假設\(3\)個數\(a<b<c\)。
則有以下幾種組合計算結果:
\(1.(a×b+1)×c+1= abc + c + 1\)
\(2.(a×c+1)×b+1= abc + b + 1\)
\(3.(b×c+1)×a+1= abd + a + 1\)
顯然,選擇兩個較小數能得到最大的結果,而選擇兩個較大的數能得到最小的結果,上述算法的正確性得證。推廣至n個數,該算法的單調性也顯而易見。
#include <bits/stdc++.h> #define _for(i,a,n) for(int i=a;i<n;++i) #define rep(i,a,n)for(int i=a;i<=n;++i) #define input() int t;cin>>t;while(t--) #define close() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) using namespace std; typedef long long ll; typedef pair<int, int> P; const int maxn = 5e4; priority_queue<int, vector<int>, greater<int> > Q1; priority_queue<int, vector<int>, less<int> > Q2; int main() { int n, t; cin >> n; _for(i, 0, n) { cin >> t; Q1.push(t); Q2.push(t); } cin >> t; int maxv = 0, minv = 0; while(Q1.size() != 1) { t = Q1.top(); Q1.pop(); t = t * Q1.top() + 1; Q1.pop(); Q1.push(t); t = Q2.top(); Q2.pop(); t = t * Q2.top() + 1; Q2.pop(); Q2.push(t); } cout << Q1.top() - Q2.top() << endl; return 0; }
「一本通 1.1 練習 1」數列極差