CSU1684-Disastrous Downtime-STL

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值