CSU1684-Disastrous Downtime-STL

来源:互联网 发布:网络诋毁企业 编辑:程序博客网 时间:2024/05/16 10:29

E: Disastrous Downtime

题目大意就是有n个请求,每个请求消耗1000秒(包含停下的那一秒),一台服务器能同时处理k个请求,给你n/k/(n个请求到达的时间),要你输出最少需要几台服务器。
思路是这样的:按照时间来看10^6的数据量,要么是一个O(nlogn)要么是一个O(n)的时间复杂度的算法,而光扫描固定次数得解的办法并没有(或者我太蠢想不到,欢迎补充),故应该是一个O(nlogn),那么很容易就想到二分。
具体的二分思路是这样的,首先将请求按照时间排序后,依次将其加入一个容器中,加入的时候采取如下操作:
若容器中的时间都在新加入的请求的到达时间之前,则删去最后一个请求,再加入;否则,直接加入。同时,加入的数据是请求处理完毕的时间,而用来比较的是请求到达的时间。
这样容器最后留下的元素个数就是最多的时候有多少个请求,假如这个数目是a,则答案就是ceil(a/k)(ceil表示向上取证,floor表示向下取整)
现在证明算法的正确性:
首先假如在容器为空的时候,显然直接加入就行,这个是没错的;当容器非空时,若是找不到离开时间比现在这个请求处理结束时间晚的请求,则删去一个请求并加入新的请求,并且此时有这个限制条件,所以同时最多的请求数并不会更新;若找到了(存在一个时间使这两个请求同时在服务器),则直接把进的新请求加入容器即可。
此时还不知道为什么要二分,现在回忆我们的算法,需要做到这几个关系:要找到一个【lower_bound】,找不到就是找不到处理结束时间比现在这辆请求到达时间晚的请求,找到了以后就要【删除】这个请求。
所以这个容器要很容易维护一个【有序】,并且可以采用【lower_bound方法】,同时还容易【删除】,此外请求可能会有同时到达的,所以【重复元素】也是必须的,所以用什么容器也就很明显了——multiset.
然后就是AC代码:

#include <bits/stdc++.h>#define N 10100#define INF 0x3f3f3f3f#define LL long long#define mem(a,n) memset(a,n,sizeof(a))#define fread freopen("in.txt","r",stdin)#define fwrite freopen("out.txt","w",stdout)using namespace std;int syst[10*N];int main(){    ios::sync_with_stdio(false);    int n,m;    multiset<int,greater<int> > ans;    multiset<int,greater<int> >::iterator it;    while(cin>>n>>m){        ans.clear();        for(int i=0;i<n;++i){            cin>>syst[i];    }        sort(syst,syst+n);        ans.insert(syst[0]+1000);        int cnt;        for(int i=1;i<n;++i){            it=ans.lower_bound(syst[i]);            if(it==ans.end()){                ans.insert(syst[i]+1000);            }else if(it!=ans.end()){                ans.erase(it);                ans.insert(syst[i]+1000);            }        }        cnt=ans.size();        if(cnt%m){        cnt=cnt/m+1;        }else{            cnt=cnt/m;        }        cout<<cnt<<endl;    }    return 0;}
原创粉丝点击