Educational Codeforces Round 69 (Rated for Div. 2)
最近一周一直在浪,正好晚上有一场div2的CF就打打看恢复一下手感…顺便看看自己有多菜并疯狂受苦
A
排个降序把最大的两个木板拿出来即可知道k最大可以取到多少,之后再比较n - 2与kmax的关系,取其较小的即为 可取到的最大值。
B
注意到第二个要求中要求移出处只能有一个圆盘,这极大的简化了题目。不然,考虑这样一种排列:5 6 3 4 2 1,先将5移到6后,再把3移到左边去,4就可以移到56的上面。有了仅有一个圆盘的限制后,就不允许这种横跨过底座的情况发生。那么显然只要整体序列呈一个山峰形状即可。
C
这道题的突破点在于保证输入 不减 的序列,那么要把这一段斜坡划分成m段,并且求这m段高度之和的最小值,其实就是找m - 1个断点,这些断点的间隔越大,区间高度和便越小(因为这些区间高度和与断点间隔一起构成这个斜坡的高度),那么对差值排序减去最大的m个即可得出答案。
这道题体现了一种 等价转化 的思想。而不是树状数组这样的区间查询问题
D晚上打的时候脑子实在糊涂了,想到了st表云云的,但是day6-day10的博客我都没有好好补:) 所以这样一道dp求最大子串和的题都一点没有想到是dp…
我们参考最大子串和的求法,定义dp数组:dp[i]表示取遍以i为终点的长度为m的区间内所有的点后,区间[0, i]可以达到的最大值。得到如下递推关系:相比于一般的最大子串和,这里强制取了i为终点的m区间的所有点,是因为,对于任何一个subarry,都可以用若干个m区间加上一个r区间表示,其中0 <= r < m,类似于带余除法的形式,所以这一步处理就是处理若干个m区间的情况。之后我们要做的就是遍历每一个点,以它为终点取前面若干个m区间,之后再往后取零头r区间。值得注意的是,如果r == 0,只需要比较ans和dp[i]的大小,这个时候不需要额外的减去k,因为在之前处理的时候已经处理过了了;如果r != 0,由于是题目规定是顶函数,所以从1到m都会减去一个k,之后不断的比较、更新即可。 当然了,i + j < n也是不能忘记的。
这样子考虑后其实尚不完善,test9 WA在了:5 10 10: 100 100 100 100 100的数据上。经过进一步的完善,在第一个m区间内也进行了一轮赋值:
当时没有这样子做因为感觉每一个区间都可以唯一的被表示,没有必要再进行初始化。事实上加上这一段的赋值,不仅不会让答案发生错误(顶多是出现了数量极小的重复),而且可以处理掉遗漏第一个m区间的问题。
至此总算AC。