• codeforces VK cup 2016-round 1 D.Bear and Contribution


    题意大概就是有n个数字,要使至少有k个相同,可以花费b使一个数+5,可以花费c使一个数+1,求最小花费。

    要对齐的数肯定是在[v,v+4]之间,所以分别枚举模为0~4的情况就可以了。

    排序一下,然后化绝对为相对

    例如有 3 6 8 14这4个数,模4,

    耗费分别为c+2b 3c+b c+b 0

    可以-2b(移动到14时=2*5+4,倍率2)变成c 3c-b c-b -2b

    就是说每次都取倍率然后减其花费压入优先队列,若元素数量大于k就弹出最大的那个就可以了

    /*没时间自己写个就把其他人的题解搞来了。。。*/
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <set>
    #include <map>
    #include <stack>
    #include <vector>
    #include <string>
    #include <queue>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    using namespace std;
    typedef pair<int, int> pii;
    typedef long long ull;
    typedef long long ll;
    typedef vector<int> vi;
    #define xx first
    #define yy second
    #define rep(i, a, n) for (int i = a; i < n; i++)
    #define sa(n) scanf("%d", &(n))
    #define vep(c) for(decltype((c).begin()) it = (c).begin(); it != (c).end(); it++)
    const int mod = int(1e9) + 7, INF = 0x3fffffff, maxn = 1e5 + 12;
    
    //ll que[maxn * 4];
    int ct[maxn * 2];
    
    //小根堆仿函数
    class cmp
    {
    public:
        bool operator()(const ll a, const ll b) {
             return a > b;
        }
    };
    
    int main(void) {
    #ifdef LOCAL
        freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
    #endif
        int n, k, b, c;
        while (cin >> n >> k >> b >> c) {
            rep (i, 0, n) sa(ct[i]), ct[i] += 1e9;
            sort(ct, ct + n);
            ll ans = 1ll << 60;
            if (c * 5 <= b) {
                 ll sum = 0;
                 for (int i = 0; i < n; i++) {
                     sum += ct[i];
                     if (i >= k - 1) {
                         ans = min(ans, ((ll)ct[i] * k - sum) * c);
                         sum -= ct[i - k + 1];
                     }
                 }
            } else {
                rep (md, 0, 5) {
                    ll sum = 0;
                    //int head = 0, tail = 0;
                    priority_queue<ll, vector<ll>, cmp> que;
                    rep (i, 0, n) {
                        ll cc = (md + 5 - ct[i] % 5 ) % 5;
                        ll bb = (ct[i] + cc) / 5;
                        //等效处理之后的值.
                        ll cost = bb * b - cc * c;
                        sum += cost;
                       // while (head == tail || que[tail - 1] > cost) que[tail++] = cost;
                        que.push(cost);
    
                        if (i >= k - 1) {
                             ans = min(ans, (bb * k * b - sum));
                             sum -= que.top();
                             que.pop();
                        }
                    }
                }
            }
            cout << ans << endl;
        }
    
        return 0;
    }
    View Code

    o(n)的解法?没有啦

  • 相关阅读:
    linux常用网络命令
    linux常用命令
    内核驱动——符号表的导出
    内核模块传参
    *** No rule to make target 'param'. Stop. 的问题
    mmap操作荔枝派gpio v3s Linux
    交叉编译 -sh: ./xxx: not found 的问题
    linux驱动 第一个驱动
    ubuntu 16.04 开机脚本
    V3s录音 交叉编译alsa linux
  • 原文地址:https://www.cnblogs.com/dgutfly/p/5922410.html
Copyright © 2020-2023  润新知