题:https://codeforces.com/contest/1355/problem/E
题意:对于高度数组a[],目的是将所有高度平齐,有三种操作:1、a[i]--代价为R;2、a[i]++代价为A;3、将某一位置的一个单位转移到另一个位置 代价为M,问最小代价能平齐的高度;
分析:答案具有峰值性,即在极限的情况下,随着ans的减少,代价变多,随着ans增加,代价变多。那么这种情况就考虑三分!;
因为操作三的贪心是min(M,A+R),所以check函数就是能补的就补,不能补的就靠操作1、2来弥补
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
const int inf=0x3f3f3f3f;
const ll INF=1e18;
const int M=1e6+3;
const int mod=1e9+7;
ll ksm(ll x,ll y){
ll t=1;
while(y){
if(y&1)
t=(t*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return t;
}
void pn(){
cout<<"no"<<'n';
}
void py(){
cout<<"yes"<<'n';
}
int nex[]={0,0,1,-1};
int ney[]={1,-1,0,0};
int n,A,R,minn;
int a[M];
ll check(int x){
ll suma=0,sumb=0;
for(int i=1;i<=n;i++){
if(a[i]<x)
suma+=x-a[i];
if(a[i]>x)
sumb+=a[i]-x;
}
ll tmp=min(suma,sumb);
suma-=tmp,sumb-=tmp;
return 1ll*suma*A+1ll*sumb*R+1ll*tmp*minn;
}
int main(){
cin>>n>>A>>R>>minn;
for(int i=1;i<=n;i++)
cin>>a[i];
minn=min(minn,A+R);
int l=0,r=inf,ans;
while(l<r){
int lmid=l+((r-l)/3);
int rmid=r-((r-l)/3);
if(check(lmid)<check(rmid))
r=rmid-1;
else
l=lmid+1;
}
cout<<check(l)<<'n';
return 0;
}
View Code
原文链接: https://www.cnblogs.com/starve/p/12904202.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/197509
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!