zoukankan      html  css  js  c++  java
  • CF505E Mr. Kitayuta vs. Bamboos

    XXX.CF505E Mr. Kitayuta vs. Bamboos

    “最大值最小”,条件反射套个二分上去。

    于是现在问题转变成判定型问题。

    正着搞不好处理 \(\max(h_i-p,0)\) 这种套了 \(\max\) 的限制,干脆正难则反,考虑倒着处理。

    于是问题转变为 第 \(i\) 天开头所有竹子高度减少 \(a_i\),然后你可以选几棵再给它补回来 \(p\)。目标是所有竹子在结尾时高度不低于 \(h_i\),但同时还要保证任意时刻竹子高度不会被减成负数。

    如何构造补竹子的顺序呢?考虑贪心——每次总是补那些最快被减成负数的竹子。换句话说,可以用一颗堆来维护所有在结尾时高度低于 \(h_i\) 的竹子,因为竹子只要保证最终高度符合要求,对中间的高度除了非零外别无要求,所以此种贪心正确。当前高度不合法,当且仅当某一时刻竹子出现负数或者是最终堆非空(意味着尚有高度不合要求的竹子)。

    时间复杂度 \(O(n\log^2n)\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int n,m,k,p,h[100100],a[100100];
    struct dat{
    	ll tim,tot;
    	int id;
    	dat(ll A,ll B,int C){tim=A,tot=B,id=C;}
    	friend bool operator<(const dat&u,const dat&v){return u.tim>v.tim;}
    };
    priority_queue<dat>q;
    bool che(ll ip){
    	while(!q.empty())q.pop();
    	for(int i=1;i<=n;i++)if(ip-1ll*m*a[i]<h[i])q.push(dat(ip/a[i],ip,i));
    	for(int i=1;i<=m;i++){
    		if(!q.empty()&&q.top().tim<i)return false;
    		for(int j=1;j<=k;j++)if(!q.empty()){
    			dat x=q.top();q.pop();
    			x.tot+=p,x.tim=x.tot/a[x.id];
    			if(x.tot-1ll*m*a[x.id]<h[x.id])q.push(x);
    		}
    	}
    	return q.empty();
    }
    int main(){
    	scanf("%d%d%d%d",&n,&m,&k,&p);
    	for(int i=1;i<=n;i++)scanf("%d%d",&h[i],&a[i]);
    	ll l=1,r=1e14;
    	while(l<r){
    		ll mid=(l+r)>>1;
    		if(che(mid))r=mid;
    		else l=mid+1;
    	}
    	printf("%lld\n",r);
    	return 0;
    }
    

  • 相关阅读:
    REQUIRED与REQUIRED_NEW
    springboot启动原理
    Mysql缓存的配置和使用
    Mysql-15-mysql分布式应用
    Mysql的日志管理
    Mysql的主从复制
    Mysql的备份和恢复
    Mysql-7-mysql函数
    Mysql-6-数据类型和运算符
    Mysql-5-数据表的基本操作
  • 原文地址:https://www.cnblogs.com/Troverld/p/14611559.html
Copyright © 2011-2022 走看看