codeforces514D(二分+ST)
- 题目链接
- 题目大意:有n个机器人,一共有m个零件,可以进行k次射击,每次射击都可以选择一种零件进行射击即每个机器人的该种零件数都-1,如果一个机器人的所有零件数均为0则该机器人被销毁,问怎么分配这k次射击可以得到最长的连续的被销毁的机器人
- 解题思路:
- 先是废话完全没思路这周个人赛再一次打击了我的自信心,我觉得自己太菜了,还是遇到一道连思路也没有,自己知道的算法太少了,字典树从来没写过,线段树做过几道题不过已经忘了,有点怀疑人生,不过感谢shz学长给我鼓励,还是好好加油吧,与其想东想西不如先把题补了。在这里立个flag,这周练习赛我要做写题最多的那个人。
- 这道题的整体思路就是二分枚举最长连续区间的长度,我觉得自己最近做的题想法都好巧妙啊,都不是那种按照题目思路直接去想,而是要换一个角度
- 怎么判断mid呢?以样例一为例,比如我们要把零件一全都销毁,我们需要射击的次数是 max(4,1,2,0,1) m a x ( 4 , 1 , 2 , 0 , 1 ) 也就是说如果在某个区间的某一个零件全被消灭需要的射击次数就是这个区间了该零件的最大的那个数量,我们只要枚举区间的左端点,把去每个零件在这个区间的最大值相加就是这个区间要是机器人全被消灭需要的射击次数,然后跟k比
- 查询区间的最大值用到了ST表的做法,这是我第一次写ST表,如果哪里写的不太对了欢迎指出,非常非常感谢,感觉智商不够用,ST表是用来查询区间最值(RMQ)没有更新的情况,ST表需要先进行预处理,这样就可以保证每次查询时O(1)的复杂度,用到的思想是dp, dp[i][j] d p [ i ] [ j ] 表示的意思是从i开始到 i+2j i + 2 j 的最值,状态转移方程是 dp[i][j]=max(dp[i][j−1],dp[i+(1<<j)][j]] d p [ i ] [ j ] = m a x ( d p [ i ] [ j − 1 ] , d p [ i + ( 1 << j ) ] [ j ] ] 就是把区间分成了两部分,比较前后两部分的最值,确定整个区间的最值,还有要注意的一点预处理的时候枚举区间的长度在外循环,起始点的枚举在内循环
- AC代码参考了这个博客就不放了