• 漩涡般的阴谋


    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;
    }
    
  • 相关阅读:
    SQL进阶-索引设置&sql优化
    SQL进阶-去重
    SQL进阶-隐式类型转换
    SQL进阶-行转列&列转行
    用Spring实现文件上传(CommonsMultipartFile)!
    在Maven父项目下创建子项目
    Maven下把父项目下的子项目导出到myeclipse中
    oracle数据库的导入导出命令
    配置环境变量
    Nginx反向代理的配置
  • 原文地址:https://www.cnblogs.com/qswx/p/9492548.html
Copyright © 2020-2023  润新知