題意#
這題給定 \( n \) 根長度不同的木棍,目標是將它們修改為相同長度。
你可以任意把每一根木棍切短或接長,每改變 \( 1 \) 單位的長度就會消耗 \( 1 \) 的成本。
我們需要求出達成目標的最小總花費。
思路#
要讓所有數字變成某個目標值,並使「差值的絕對值」總和最小,目標點應為這群數字的「中位數」。
平均數是讓「差值的平方和」最小的基準點。若將木棍長度視為數線上的點,
只有目標長度停留在中位數時,左右兩側的木棍數量才會大致平衡,使總距離和最小。
在實作上,先對所有長度進行排序以找出中位數,
再計算每根木棍和中位數的長度差並將其加總。
如果 \( n \) 是偶數,選擇中間兩個數字的任何一個作為目標均可。
程式碼#
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define INF LONG_LONG_MAX/1000
#define WA() cin.tie(0)->sync_with_stdio(0)
#define all(x) (x).begin(), (x).end()
#define int long long
#define PII pair<int, int>
signed main() { WA();
int n; cin >> n;
vector<int> v(n);
// 讀入所有木棍長度後,直接進行排序
for (auto &i : v) cin >> i; sort(all(v));
int k, sum = 0;
// 根據總數是奇數還偶數,找出中位數 k
if (n&1) k = v[n/2];
else k = v[n/2-1];
// 計算所有木棍與中位數的距離差總和
for (auto &i : v) sum += abs(i-k);
cout << sum << '\n';
}
