• 「CF505E」 Mr. Kitayuta vs. Bamboos


    「CF505E」 Mr. Kitayuta vs. Bamboos

    传送门

    如果没有每轮只能进行 (k) 次修改的限制或者没有竹子长度必须大于 (0) 的限制那么直接贪心就完事了。

    但是很遗憾。

    首先看到最小化最大值可以想到用二分将最优化问题转化为判定性问题。

    设当前二分的值为 (H)

    但是有这个必须大于 (0) 的限制很烦,导致我们不一定能真的减少 (p),所以我们考虑让时光倒流。

    即:假设所有的竹子最后都满足限制,即均为 (H)。每一次长高就相当于减少 (a_i),每次你可以选择 (k) 根竹子使其长高 (p),问最后竹子高度是否都 (ge h_i)

    然后我们每一轮将最有可能掉为负数的那些竹子拉出来长高,用一个堆维护就完事了。

    代码:

    /*---Author:HenryHuang---*/
    /*---Never Settle---*/
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+5;
    ll n,m,k,p;
    ll h[maxn],a[maxn];
    ll high[maxn];
    bool check(ll x){
    	priority_queue<pair<int,int> > Q;
    	for(int i=1;i<=n;++i) if(x-m*a[i]<h[i]) Q.emplace(-x/a[i],i);
    	for(int i=1;i<=n;++i) high[i]=x;
    	for(int i=1;i<=m;++i)
    		for(int j=1;j<=k;++j){
    			if(Q.empty()) return 1;
    			auto now=Q.top();Q.pop();
    			if(-now.first<i) return 0;
    			high[now.second]+=p;
    			now.first=-high[now.second]/a[now.second];
    			if(high[now.second]-m*a[now.second]<h[now.second]) Q.emplace(now);
    		}
    	return Q.empty();
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0),cout.tie(0);
    	cin>>n>>m>>k>>p;
    	for(int i=1;i<=n;++i) cin>>h[i]>>a[i];
    	ll l=*min_element(a+1,a+n+1),r=1ll<<60,ans=r;
    	while(l<=r){
    		ll mid=(l+r)>>1;
    		if(check(mid)) ans=min(ans,mid),r=mid-1;
    		else l=mid+1;
    	}
    	cout<<ans<<'
    ';
    	return 0;
    }
    
    在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。
  • 相关阅读:
    走向变态的人生
    HDWIKI 4.0.2绿色版(含运行环境)(V1)
    centos7 安装python3.7.1
    一种高并发流控程序的简单轻量实现
    编写JDBC框架优化CRUD操作
    一段阻塞队列代码的纠错与优化
    一次请求在同一个事务实现
    创建Java内部类的编译错误处理
    C++模板简单分析与举例
    java.lang.OutOfMemoryError处理错误
  • 原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/solution-CF505E.html
Copyright © 2020-2023  润新知