Mr. Kitayuta vs. Bamboos

题目链接:http://codeforces.com/problemset/problem/505/E

参考:http://blog.csdn.net/qpswwww/article/details/46316647

贪心,二分

从数据规模上看,算法复杂度只能为O(n)或者O(nlgn),似乎不能直接求值,考虑二分MAX将求值问题转化为判定性问题。然而考虑到砍伐后竹子高度变为0的特殊情况,考虑倒着做,即初始时每个竹子高度均为MAXi,每天晚上每个竹子会减少高度a[i],每天白天可以选择对其中不超过K个竹子选择将其的高度增加P,并且保证任何时刻任何竹子高度均大于等于0,m天后是否可以让每个竹子高度均大于等于h[i]。

证明倒着推的正确性:只有在m天后每个竹子高度均大于等于h[i],才能让所有的竹子按照原来正向的顺序,以和倒着做相同的操作反过来让每个竹子最终的高度小于等于MAXi,见下图,绿色线代表倒着推的话一根竹子的每天生长情况,蓝色线代表正着推的话一根竹子的每天生长情况(来自Codeforces官方题解)

可以发现如果每天对这个竹子的操作相同的话,要想让最后的这个竹子的高度和倒着推的高度一样,之前每天正着推的高度都必须小于等于倒着推的高度。

首先计算从MAXi开始,最多经历多少天自由生长(减少高度a[i]),竹子的高度变为负数,然后用一个小顶堆维护竹子变为负数的天数(时间越小,越快变为负数),每天取k个竹子进行砍伐(拔高处理)。若存在某一天来不及拔高竹子(存在某个竹子的高度在这一天之前就变为0了),就可以立刻判定m天后不能可以让每个竹子高度均大于等于h[i]。

现在我们让所有竹子倒过来生长,最终每个竹子高度均大于等于0后,就需要让每个竹子的高度拔高,使得它们最终高度大于等于h[i],显然此时由于在生长过程中,每个竹子在任意时刻高度均大于等于0,故此时补充的操作无论是在何时发生都是一样的。这时直接通过数学方法,计算每个竹子和h[i]之间相差的高度以考虑需要补上多少次操作就够了。

这道题是看着题解跪着做完的Orz,感觉对二分的理解更深了一些,二分处理的都是判定性问题,不能直接求值。

代码如下:

 1 #include<cstdio>
 2 #include<queue>
 3 #include<iostream>
 4 #define N 100000
 5 #define LL long long
 6 #define mid ((l+r)>>1)
 7 using namespace std;
 8 const LL MAX=1e15;
 9 LL n,m,k,p,l,r;
10 LL h[N+5],a[N+5];
11 LL now[N+5];
12 typedef pair<LL,LL> P;
13 struct cmp{
14     bool operator()(P a,P b){
15         return a.first>b.first;//小顶堆
16     }
17 };
18 bool judge(LL x){
19     priority_queue<P,vector<P>,cmp> q;
20     for(LL i=0;i<n;++i){
21         now[i]=x;//刚开始竹子的高度为MAXi
22         if(x-m*a[i]>=0)continue;//不需要补充高度
23         q.push(make_pair(x/a[i],i));//P(到零的天数,下标)
24     }
25     LL times=0;//砍伐次数
26     for(;times<=k*m;times++){
27         if(q.empty())break;
28         P temp=q.top();
29         q.pop();
30         if(temp.first<=times/k)return 0;//来不及补充高度,竹子在k天前就长成负数
31         LL index=temp.second;
32         now[index]+=p;
33         if(now[index]-m*a[index]>=0)continue;//不需要补充高度
34         q.push(make_pair(now[index]/a[index],index));
35     }
36     if(times>k*m)return 0;
37     for(int i=0;i<n;++i){
38         LL temp=m*a[i]+h[i]-now[i];
39         if(temp<=0)continue;
40         else times+=((temp/p)+(LL)(temp%p!=0));//到h[i]还需要多少次补充高度
41         if(times>k*m)return 0;
42     }
43     return 1;
44 }
45 int main(void){
46     scanf("%I64d%I64d%I64d%I64d",&n,&m,&k,&p);
47     l=1,r=MAX;
48     for(LL i=0;i<n;++i)
49         scanf("%I64d%I64d",&h[i],&a[i]);
50     while(l<r){//二分
51         if(judge(mid))r=mid;
52         else l=mid+1;
53     }
54     printf("%I64d\n",l);
55 }

转载于:https://www.cnblogs.com/barrier/p/5783897.html

Mr. Kitayuta vs. Bamboos相关推荐

  1. CF506C Mr. Kitayuta vs. Bamboos

    CF506C Mr. Kitayuta vs. Bamboos 有nnn个竹子,第iii棵竹子第一天之前的高度是hih_ihi​,每一天的末尾会长高aia_iai​ 每一天你可以将砍kkk刀,每一刀将 ...

  2. [CF505E]Mr. Kitayuta vs. Bamboos/[海军国际项目办公室]迷途竹林

    Mr. Kitayuta vs. Bamboos 迷途竹林事实上就是经TiwAirOAO\color{red}{TiwAirOAO}TiwAirOAO巨佬扩大数据范围强化后的版本.真的是强化了吗 不过 ...

  3. 【IOI2020国家集训队作业 Part 1】CF505E Mr. Kitayuta vs. Bamboos

    题目 题目描述 Mr. Kitayuta's garden is planted with nn bamboos. (Bamboos are tall, fast-growing tropical p ...

  4. [CF506C]Mr. Kitayuta vs. Bamboos

    Description 有n个竹子,第i个竹子长度为h[i],每天的结束会长高a[i] 现在有m天,每一天可以做k次操作,每次操作可以选择一个竹子砍掉p,即高度h[i]=max(h[i]-p,0) 你 ...

  5. Mr. Kitayuta vs. Bamboos[二分+贪心][图像分析]

    文章目录 题目 思路 代码 题目 思路 首先最大值最小考虑二分,假设我们检验 xxx 但是发现检验比较难写 尝试从图像分析 那么画出来图像大致如下: 然后我们发现可以将图像上移末端重合至 (m,x)( ...

  6. CF506 C Mr. Kitayuta vs. Bamboos (贪心)

    题意 有n根竹子,初始高度是h[i],每天结束时会长高a[i],每天你可以砍K刀,一刀能减小p的高度.可以在某一天内砍相同的竹子多次.问m天结束后,最高的竹子最矮是多高. n≤1e5,k≤10,m≤5 ...

  7. 【每日一题】8月12日题目精讲 Mr. Kitayuta, the Treasure Hunter

    来源:牛客网: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 The Shuseki I ...

  8. 505B. Mr. Kitayuta‘s Colorful Graph

    B. Mr. Kitayuta's Colorful Graph:题目 一开始就像到了DFS,并查集也不难想到. 弗洛伊德算法倒是不容易想到,平时不这么用..... #include <bits ...

  9. Mr. Kitayuta‘s Technology CodeForces - 505D(并查集+拓扑排序或dfs找环) 题解

    题目  Shuseki Kingdom is the world's leading nation for innovation and technology. There are n cities ...

最新文章

  1. 招募 | 《大数据实践课》企业合作项目,2020年夏季学期“清华大学大数据能力提升项目”...
  2. 【转】java读写二进制文件的解决方法
  3. 对勾选的下拉选择进行同步选择
  4. VS2010静态编译
  5. 超详细Ubuntu Linux安装配置 Tomcat
  6. 数据结构与算法--举例分析法- 栈的压入弹出序列
  7. Android Input 子系统初探
  8. springboot 讯飞语音_讯飞智能语音鼠标实际体验感受
  9. SOTA级发丝抠图模型PP-Matting重磅开源,支持多场景精细化分割!
  10. Python 详解九九乘法表
  11. linux运行崩溃怎么定位,Linux 程序崩溃定位
  12. 会声会影2022测试新版本号V25.0.0.373
  13. 建建自学VoIP之VAD(Voice Activity Detector)和CNG(Comfort Noice Generator)
  14. 04_消息中心(MessageCenter)
  15. 《云》赏析-[唐]来鹄古诗
  16. 盘点HR日常工作数据计算大全
  17. O2O、C2C、B2B、B2C、F2C的区别在哪里?
  18. 【Pytorch】区分detach()和torch.no_grad()
  19. 消除Django的RuntimeWarning:DateTimeField警告
  20. ps4中文版下载 photoshop cs4绿色版 v11.0

热门文章

  1. 【嵌入式学习-STM32F103-EXTI外部中断】
  2. 【C#】WinForm 之 SQL Server 服务监控器(避免开机启动服务)
  3. Java实现 LeetCode 41 缺失的第一个正数
  4. UOS启用wayland
  5. 深度链接、延迟深度链接、App Links以及关于LinkedME实现深度链接的原理解析
  6. 51单片机调整时钟Proteus仿真
  7. 地理位置与经纬度之间相互转换(基于python调用百度API)
  8. 幻灯片更换模板_如何创建Google幻灯片模板
  9. centos+7虚拟机web服务器,CentOS7上搭建WEB服务器
  10. 【射影几何02】拓广平面