zoukankan      html  css  js  c++  java
  • CF1355E Solution

    题目链接

    题解

    如果(M>A+R)的话(可能还要加上些奇奇怪怪的条件,总之就是全部弄成(M)最优的情况),把高度变为平均数一定最优,这样可以最大化使用(M)。如果(M)没有太大用处,而是要在(A,R)之间找平衡的话,可以发现最终高度一定为某个柱子的高度。简单证明:将(h)数组升序排序,设(h_i<res<h_{i+1})(res)为最终高度)。若(A>R),将(res)调至(h_i)可以使花费减少(icdot (res-h_i)cdot (A-R));若(A<R),将(res)调至(h_{i+1})可以使花费减少((n-i)cdot (h_{i+1}-res)cdot (R-A));若(A=R),则等于多少都无所谓。

    因此求出取平均数时的花费与取每个柱子时的花费就可以啦,时间复杂度(O(n))

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e5+10;
    int h[N],sum[N],n,a,r,m;
    int sol(int x,int op)
    {
    	int pos;
    	if(!op) pos=lower_bound(h+1,h+n+1,x)-h-1;//其实不需要二分
    	else pos=op;
    	int qwq=min(pos*x-sum[pos],sum[n]-sum[pos]-(n-pos)*x);
    	return qwq*m+(pos*x-sum[pos]-qwq)*a+(sum[n]-sum[pos]-(n-pos)*x-qwq)*r;
    }
    signed main()
    {
    	scanf("%lld%lld%lld%lld",&n,&a,&r,&m); m=min(a+r,m);
    	for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
    	sort(h+1,h+n+1);
    	for(int i=1;i<=n;i++) sum[i]=sum[i-1]+h[i];
    	int ans=min(sol(sum[n]/n,0),sol(sum[n]/n+1,0));//平均数可能是小数,上下取整都试一下
    	for(int i=1;i<=n;i++) ans=min(ans,sol(h[i],i));
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    读Javascript MDN之闭包
    观察者模式小探
    javascript之克隆
    element-vue的简单使用
    页面加载海量数据
    手把手教你入门微信公众号开发
    ES6 Promise 用法讲解
    Javascript模块化编程(三):require.js的用法
    Javascript模块化编程(二):AMD规范
    Javascript模块化编程(一):模块的写法
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14633750.html
Copyright © 2011-2022 走看看