一个不错的讲三分的文章(44条消息) 算法思想-三分_舍舍发抖的博客-CSDN博客_算法中三分法的基本思想是
题意:给定n个柱子,每个柱子的高度为h[i](h[i]块砖),要求将全部柱子操作成相同的高度,有以下三种操作:
1.增加一块砖 花费a
2.移走一块砖(柱子的高度>0) 花费b
3.将一块砖从一个柱子移动到另一个柱子 花费c
问要想满足要求最少要花费多少。
思路:
容易得知花费是存在极小值点的且只有一个,所以三分墙的高度即可。check的时候,要贪心的去算将每个柱子的高度变为x的花费。如果c<=a+b,显然对于多的或少的砖用移动可以能得到较少的花费。
#include<bits/stdc++.h>
#define int long long
#define pdd pair<double,double>
#define pii pair<int,int>
// #define x first
// #define y second
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int N=1e5+10;
int n,a,b,c;
int h[N];
int sum;
int check(int x){
int res=0;
int d=0,s=0;
for(int i=1;i<=n;i++){
if(h[i]>x) d+=h[i]-x;
if(h[i]<x) s+=x-h[i];
}
if(c<=a+b){
res+=min(d,s)*c;
if(d>s) res+=b*abs(d-s);
else res+=a*abs(d-s);
}
else{
res+=d*b;
res+=s*a;
}
return res;
}
void solve(){
cin >> n >> a >> b >> c;
for(int i=1;i<=n;i++) cin >> h[i],sum+=h[i];
sort(h+1,h+n+1);
int l=h[1],r=h[n];
while(l<r){
int midl=l+(r-l)/3;
int midr=r-(r-l)/3;
if(check(midl)>check(midr)) l=midl+1;
else r=midr-1;
}
cout << check(l) << endl;
}
signed main(){
ios;
int t=1;
// cin >> t;
while(t--){
solve();
}
return 0;
}