题目链接
题目大意
给你一个数组,要你使数组所有元素的值都相等且所消耗最小代价,增加1消耗a,减少1消耗r,转移1消耗m,求消耗最小代价
题目思路
如果增加减少都是1,转移是2,那么就是类似于仓库选址问题,直接找中位数,而这个不是,就是稍微改编了一下,三分一下就行了
代码
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n,a,r,m,h[maxn];
ll check(int x){
ll down=0,up=0,ans=0;
for(int i=1;i<=n;i++){
if(h[i]<x){
up+=x-h[i];//增加
}else{
down+=h[i]-x;//减少
}
}
if(down>up){
ans+=(down-up)*r;
}else{
ans+=(up-down)*a;
}
ans+=m*min(down,up);
return ans;
}
int main(){
scanf("%d %d %d %d",&n,&a,&r,&m);
for(int i=1;i<=n;i++){
scanf("%d",&h[i]);
}
m=min(m,a+r);//预处理
int l=0,r=1e9,ans;
while(l<=r){
int mid1=l+(r-l)/3,mid2=r-(r-l)/3;
if(check(mid1)<=check(mid2)){
ans=mid1;
r=mid2-1;
}else{
l=mid1+1;
}
}
printf("%lld\n",check(ans));
return 0;
}