zoukankan      html  css  js  c++  java
  • hihoCoder | 优化延迟

    http://hihocoder.com/contest/hiho136/problem/1

    描述

    小Ho编写了一个处理数据包的程序。程序的输入是一个包含N个数据包的序列。每个数据包根据其重要程度不同,具有不同的"延迟惩罚值"。序列中的第i个数据包的"延迟惩罚值"是Pi。如果N个数据包按照<Pi1, Pi2, ... PiN>的顺序被处理,那么总延迟惩罚

    SP=1*Pi1+2*Pi2+3*Pi3+...+N*PiN(其中i1, i2, ... iN是1, 2, 3, ... N的一个排列)。

    小Ho的程序会依次处理每一个数据包,这时N个数据包的总延迟惩罚值SP为

    1*P1+2*P2+3*P3+...+i*Pi+...+N*PN

    小Hi希望可以降低总延迟惩罚值。他的做法是在小Ho的程序中增加一个大小为K的缓冲区。N个数据包在被处理前会依次进入缓冲区。当缓冲区满的时候会将当前缓冲区内"延迟惩罚值"最大的数据包移出缓冲区并进行处理。直到没有新的数据包进入缓冲区时,缓冲区内剩余的数据包会按照"延迟惩罚值"从大到小的顺序被依次移出并进行处理。

    例如,当数据包的"延迟惩罚值"依次是<5, 3, 1, 2, 4>,缓冲区大小K=2时,数据包被处理的顺序是:<5, 3, 2, 4, 1>。这时SP=1*5+2*3+3*2+4*4+5*1=38

    现在给定输入的数据包序列,以及一个总延迟惩罚阈值Q。小Hi想知道如果要SP<=Q,缓冲区的大小最小是多少?

    输入

    Line 1: N Q

    Line 2: P1 P2 ... PN

    对于50%的数据: 1 <= N <= 1000

    对于100%的数据: 1 <= N <= 100000, 0 <= Pi <= 1000, 1 <= Q <= 10^13

    输出

    输出最小的正整数K值能满足SP<=Q。如果没有符合条件的K,输出-1。

    样例输入

    5 38
    5 3 1 2 4
    

    样例输出

    2
    

    分析

    缓冲区最小是1,最大是N。可以利用二分法搜索最小的满足要求的缓冲区大小。二分的过程中需要计算SP值,可以利用优先队列/最大堆计算。

    时间复杂度:
    二分:O(log N)
    计算SP值:O(N log N)
    总复杂度:O(N (log N)^2)

    注意所有变量开long long!!!

    C++

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <queue>
    
    using namespace std;
    
    long long N, Q;
    long long P[100005];
    
    long long get_SP(int size_buf)
    {
        long long sp = 0;
        priority_queue<int> pq;
        int i = 1;
        while (i <= size_buf) {
            pq.push(P[i++]);
        }
        int weight = 1;
        while (!pq.empty()) {
            long long p = pq.top(); pq.pop();
            sp += weight * p; weight++;
            if (i <= N) pq.push(P[i++]);
        }
        return sp;
    }
    
    int solve()
    {
        int start = 1, end = N;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            long long sp = get_SP(mid);
            if (sp > Q) start = mid;
            else        end = mid;
        }
        if (get_SP(start) <= Q) return start;
        if (get_SP(end) <= Q) return end;
        return -1;
    }
    
    int main()
    {
        cin >> N >> Q;
        for (int i = 1; i <= N; ++i) scanf("%lld", &P[i]);
        cout << solve() << endl;
    }
    
    
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/ilovezyg/p/6389017.html
Copyright © 2011-2022 走看看