码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4868

时间:2017-04-27 00:27:42      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:int   const   gif   class   ace   src   std   can   namespace   

http://www.lydsy.com/JudgeOnline/problem.php?id=4868

三分+贪心

我们可以知道这是一个单峰函数

当A>B那么我们每次调整一个的价钱是最佳的,所以全部用B,如果A<B,那么我们尽量用A,不行再用B

技术分享
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
int n, m;
ll A, B, C;
ll b[N], t[N];
ll check(ll T)
{
    ll tot1 = 0, tot2 = 0, cost = 0;
    for(int i = 1; i <= m; ++i) if(b[i] > T) tot1 += b[i] - T; else tot2 += T - b[i];
    for(int i = 1; i <= n; ++i) if(t[i] < T) cost += C * (T - t[i]);
    if(A > B) cost += tot1 * B; else cost += min(tot1, tot2) * A + (tot1 - min(tot1, tot2)) * B;     
    return cost;
}
int main()
{
    scanf("%lld%lld%lld", &A, &B, &C);
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) scanf("%lld", &t[i]);
    for(int i = 1; i <= m; ++i) scanf("%lld", &b[i]);
    if(C >= 10000000000000000ll)
    {
        ll lim = 10000000000000000ll;
        for(int i = 1; i <= n; ++i) lim = min(lim, t[i]);
        printf("%lld\n", check(lim));
        return 0;
    } 
    ll l = 1, r = 100010;
    while(r - l > 2)
    {
        ll lm = (2 * l + r) / 3, rm = (2 * r + l) / 3;
        ll val1 = check(lm), val2 = check(rm);
        if(val1 > val2) l = lm; else r = rm;
    }
    printf("%lld\n", min(min(check((2 * l + r) / 3), check((2 * r + l) / 3)), min(check(l), check(r))));
    return 0;
}
View Code

 

bzoj4868

标签:int   const   gif   class   ace   src   std   can   namespace   

原文地址:http://www.cnblogs.com/19992147orz/p/6771600.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!