zoukankan      html  css  js  c++  java
  • 漩涡般的阴谋

    Description

    机房一条街有n个机房,第i个机房的坐标为xi,小X的家坐标为0。小X在街上移动的速度为1,即从x1到x2所耗费的时间为|x1 - x2|。

    每个机房的学生数量不同,ACM题目水平也良莠不齐,小X到达第i个机房后,可以花ti时间想题然后瞬时AK:当然,也可以过机房而不入。

    小X现在只有m个单位时间,之后他就该赶首去打codeforces了。现在他想知道自己最多能在多少个机房AK,希望你帮帮他。

    Analsis

    如果已确定了到达机房的最大深度,那么是不是可以用贪心解决呢?很显然是的,只要优先打耗时短的题目自然就可以AK最多的机房。

    对于深度的选择,可能会想到二分?但是研究一下可以发现,机房的深度问题不具有有序性,即靠后的机房也可能有耗时短使结果更优的,那么只能朴素枚举1~n。深度选择无法优化、为了过掉这题,要把贪心操作限制在O(logn)以内。找冗余计算可以发现对于前i个机房而言,前i-1个机房反复处理太多次,真正需要更新处理的只有第i个。判断第i个是否会影响对机房的选择,只要将其与以选入的机房堆比较,如果多做一个不会超过时间,自然直接AK掉;如果超时了那就与已选的最耗时的比较,更优就替换,不如就不管。堆处理的操作刚好是O(logn),这题就过掉了。

    Code

    #include <bits/stdc++.h>
    
    #define ll long long
    
    int n,sum,ans;
    ll m,cnt;
    std::pair<ll,ll> r[100010];
    bool flag;
    
    std::priority_queue <ll> room;
    
    void treat(ll x,ll t){
    	while(!room.empty()&&cnt+x>m){
    		cnt-=room.top();
    		sum--;
    		room.pop();
    	}
    	if(cnt+x>m){
    		flag=true;
    		return;
    	}
    	if(cnt+x+t<=m){
    		cnt+=t;
    		sum++;
    		room.push(t);
    	}
    	else if(!room.empty()&&t<room.top()){
    		cnt-=room.top()-t;
    		room.pop();
    		room.push(t);
    	}
    	ans=std::max(ans,sum);
    }
    
    int main(){
    	freopen("plan.in","r",stdin);
    	freopen("plan.out","w",stdout);
    	scanf("%d%lld",&n,&m);
    	for(int i=1;i<=n;i++)
    		scanf("%lld%lld",&r[i].first,&r[i].second);
    	std::sort(r+1,r+n+1);
    	for(int i=1;i<=n&&!flag;i++)
    		treat(r[i].first,r[i].second);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    书面采访时表示,小东西(数据库知识)
    UBuntu经常使用的操作(网络资源)
    hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分法)
    Chapter 2 User Authentication, Authorization, and Security(4):限制SA帐户管理权限
    编程算法
    iOS:WebKit内核框架的应用与解析
    协议森林03 IP接力赛 (IP, ARP, RIP和BGP协议)
    以太网,IP,TCP,UDP数据包分析
    tcp 面向连接
    TCP传输层协议的流程
  • 原文地址:https://www.cnblogs.com/qswx/p/9492548.html
Copyright © 2011-2022 走看看