E. Restorer Distance 下凸型三分

题意:给出n个墙,每个墙有一定的高度,让我们把这些墙抹平(相同的高度)

   给出三种操作,增加,删除,搬运(从高到低或者从低到高),各有各的权值

   让我们计算,抹平的最小代价

思路:很显然,当答案趋于某个高度的时候,会得到最小代价,然后依次向两边改变高度的时候,

   代价会越来越大(即下凸型)

   思路明白之后,代码就很简单,如下

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=1e5+10;
 5 ll h[maxn];
 6 ll n,a,r,m;
 7 ll check(ll x)
 8 {
 9     ll suma=0,sumb=0;
10     for(int i=1;i<=n;i++){
11         if(h[i]<=x){
12             suma+=x-h[i];
13         }
14         else sumb+=h[i]-x;
15     }
16     ll ans=0;
17     if(suma>=sumb){
18         ans+=sumb*m;
19         suma-=sumb;
20         ans+=suma*a;
21     }
22     else{
23         ans+=suma*m;
24         sumb-=suma;
25         ans+=sumb*r;
26     }
27     return ans;
28 }
29 int main()
30 {
31     scanf("%lld%lld%lld%lld",&n,&a,&r,&m);
32     if(a+r<=m) m=a+r;
33     for(int i=1;i<=n;i++){
34         scanf("%lld",&h[i]);
35     }
36     ll L=0,R=1e9;
37     ll ans;
38     while(L<R){
39         ll lmid=L+(R-L)/3;
40         ll rmid=R-(R-L)/3;
41         if(check(lmid)>check(rmid)){ //极大值求法
42             L=lmid+1;
43            // ans=check(midmid);
44         }
45         else{
46             R=rmid-1;
47           //  ans=check(mid);
48         }
49     }
50     ans=min(check(L),check(R));
51     printf("%lld\n",ans);
52     return 0;
53 }

 

posted @ 2020-09-22 23:32  古比  阅读(134)  评论(0编辑  收藏  举报