zoukankan      html  css  js  c++  java
  • 排队

    排队

    Problem:

    牛妹在银行排队等号时,观察到以下场景。
    银行有m个服务窗口,假设当前有n个人等待办理业务,那么这n个人会被顺序分配一个从1到n的号码。

    等待办理业务的流程如下:
    从第1号到第n号顺序的进行排队。
    假设当前第1号到第i-1号都正在办理或已经办理完业务,且某个窗口A没有客人正在办理业务,那么第i号会马上到窗口A办理他的业务。
    如果有多个这样的窗口,第i号会随意选择一个窗口。

    在0时刻,牛妹观察到m个窗口都没有客人正在办理业务,而n个人正在等待办理业务。
    为了简化问题,我们假设第i号不管在哪个窗口办理业务,办理业务的时间都为(a_i)​。

    牛妹想知道有多少对(i,j),满足(leq i<jleq n),且第i号办理业务完成的时间严格大于第j号办理业务完成的时间。

    Example:

    input

    5,2,[1,3,2,5,4]
    

    output

    1
    

    note

    第1号 开始办理时间 0 办理完成时间 1
    第2号 开始办理时间 0 办理完成时间 3
    第3号 开始办理时间 1 办理完成时间 3 (在1号办理完同时开始办理)
    第4号 开始办理时间 3 办理完成时间 8 (在2和3号办理完同时开始办理)
    第5号 开始办理时间 3 办理完成时间 7 (在2和3号办理完同时开始办理)
    唯一一组满足题意的(i,j)对为(4,5)

    Remark:

    对于30%数据,(1leq n,m leq 1000)

    对于100%数据,(1leq n,m leq 100000)(1leq a_i leq 1e9)

    题解:

    用优先队列模拟窗口排队计算每个人的结束时间,题中所求为完成时间数列的逆序数,数据范围到(1e5)用归并排序计算逆序数。

    Code:

    class Solution {
    public:
        /**
         * 求解合法的(i,j)对的数量
         * @param n int整型 n个人
         * @param m int整型 m个窗口
         * @param a int整型vector 长度为n的vector,顺序表示1-n号客人的办理业务所需时间
         * @return long长整型
         */
        long long tm[111111];
        priority_queue<long long,vector<long long>, greater<long long>> box;
        void Union(int L,int R,int mid,long long &sum)
        {
            long long mm[111111];
            int k=1,l=L,r=mid+1;
            while(l<=mid&&r<=R){
                if(tm[l]<=tm[r]){
                    mm[k++]=tm[l++];
                }
                else{
                    sum+=mid+1-l;
                    mm[k++]=tm[r++];
                }
            }
            while(l<=mid)
                mm[k++]=tm[l++];
            while(r<=R)
                mm[k++]=tm[r++];
            for(int i=L,j=1;i<=R;i++,j++)
                tm[i]=mm[j];
            return;
        }
        void merge(int l,int r,long long &sum)
        {
            if(l==r)
                return;
            int mid=(l+r)/2;
            merge(l, mid,sum);
            merge(mid+1, r, sum);
            Union(l, r, mid, sum);
        }
        
        long long getNumValidPairs(int n, int m, vector<int>& a) {
            // write code here
            for(int i=0;i<m;i++)
                box.push(0);
            for(int i=0;i<n;i++){
                long long mm=box.top()+a[i];
                tm[i+1]=mm;
                box.pop();
                box.push(mm);
            }
            long long ans=0;
            merge(1, n, ans);
            return ans;
        }
    };
    
  • 相关阅读:
    MDK(keil)4.7中文注释乱码解决
    小型功率放大器的设计与制作
    增强输出的电路
    晶体管电路设计学习笔记(一)
    MOSFET学习
    sysTick系统定时器
    C#面向对象 什么是面向对象
    JS基础 超链接、数列的用法,行内元素和块级元素
    JS基础 常用函数、事件、阻止事件冒泡
    JS基础 定时器【setTimeout、setInterval、clearInterval 】
  • 原文地址:https://www.cnblogs.com/LeafLove/p/13369344.html
Copyright © 2011-2022 走看看