写在前面:
本系列博客仅作为本人十一假期过于无聊的产物,对小学期的程序设计作业进行一个总结式的回顾,如果将来有BIT的学弟学妹们在百度搜思路时翻到了这一条博客,也希望它能对你产生一点帮助(当然,依经验来看,每年的题目也会有些许的不同,所以不能保证每一题都覆盖到,还请见谅)。
不过本人由于学艺不精,代码定有许多不足之处,欢迎各位一同来探讨。
同时请未来浏览这条博客的学弟学妹们注意,对于我给出完整代码的这些题,仅作帮助大家理解思路所用(当然,因为懒,所以大部分题我都只给一个伪代码)。Anyway,请勿直接复制黏贴代码,小学期的作业也是要查重的,一旦被查到代码重复会严厉扣分,最好的方法是浏览一遍代码并且掌握相关的要领后自己手打一遍,同时也要做好总结和回顾的工作,这样才能高效地提升自己的代码水平。
加油!
成绩 | 10 | 开启时间 | 2021年08月24日 星期二 09:00 |
折扣 | 0.8 | 折扣时间 | 2021年08月29日 星期日 23:00 |
允许迟交 | 否 | 关闭时间 | 2021年10月10日 星期日 23:00 |
Description
十一年前,北湖曾经是一片平整的土地,北湖的施工队打算将其挖出深坑,注水造出人工湖。
为了简化运算,我们假设北湖的地面是一维的,每一块宽度都为1,高度是非负整数,那么可以用一个数组来表达一块地面。
一开始北湖是一片平地,每一块的高度为。下图是的情况,用数组表示为[3,3,3,3,3,3,3,3,3,3,3,3]。
施工队根据图纸想将其挖成凹凸不平的形状,如下图所示,数组表示为[0,1,0,2,1,0,1,3,2,1,2,1]。
施工队有一台挖土机,每一天挖土机可以将连续一段区间挖掉一格土。包工头小张想尽快完成任务,请你告诉他将平整的土地挖成图纸所示的情况最少需要多少天?
Input
第一行输入两个整数。表示北湖的总宽度和初始每一块的高度。
接下来一行个整数,表示图纸上每一个位置的高度。
Output
一个整数表示最少几天能将北湖挖好。
Notes
9天挖土的区间为[1,7],[1,3],[5,7],[1,1],[3,3],[6,6],[9,12],[10,10],[12,12]。
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M |
题意分析:
本题首先要考虑的就是,如何挖土才能挖的最快?
我们注意到,每次只能挖一格深,那么肯定一次挖的越“长”越好,所以一个最朴素的想法就是,记录每一个高度上有多少个连续区间,如样例所示,高度为3时被第8块隔开形成了两个区间,就需要挖两次。每个高度累加起来就是答案。
然而这么做的问题在于,我们需要遍历次,有没有在常数次遍历下就可以完成的方法,甚至能够做到一次遍历边输入就边处理的方法呢?答案是肯定的。
但是这样的话,我们的贪心策略就要变动:首先,我们不再从全局的角度思考,而是从局部的角度思考,走一步算一步;其次,既然我们不从全局的角度思考,那么也就不应该考虑“挖”这个操作,因为“挖”这个操作是从最顶上向下挖,是基于全局最高点的,当我们只有局部的数据的时候,手中没有全剧最高点的信息,自然没有办法这样考虑,因此我们采用“挖”的逆操作——“填”(仔细想想,填和挖的操作步骤是不是一样的)。
具体的操作流程为,由前至后依次读入数据,如果新读入的数据大于上一个数据,则将之前的高度全部“填”至当前高度,这样就可以保证在整个遍历的过程中,操作指针左侧的所有地面都是非递增的。
为了方便理解,借用题例简单画个图讲解一下:
(绿色表示输入的数据,蓝色表示“填”的方块,红色边框表示操作指针)
Count=1
Count=1
Count=3
Count=3
Count=3
Count=4
Count=6
这样应该比较好理解了吧T^T
伪代码:
读入,,初始化一个变量为0,保存输出(记得开long long);
长为的循环:
读入,如果且,则;
跳出循环时,注意到最后一个没有后继,所以我们还需要额外进行一次累加;
输出;