A 略。
B 似乎只需要在一个方向贪心就好了,和书上说的一样,证明几种方法中,其中一种不比别的差,就是贪心了。所以必须要关一盏灯的话,因为贪心方向是向右的,所以关右边不会比关左边更差。
C 下标访问数组的时候一定要注意越界的问题,或者用map的count方法适用性更广?其实这题只需要分去掉那个数是最大的(判断第二大数是不是一半)或者不是(判断最大数是不是一半)就行了。
D 从一个数组里面求一个长度恰为k的数组t,每次从数组中恰好减去t直到不能再减,求最大减的次数的t。二分答案的模板题,尝试寻找一个可以减mid次的数组t,肯定从最多频度的数里面除以mid就得到可以加入几次这个数。验证是n复杂度,二分是logn复杂度。
E *1800 这难度居然1800而且更关键的是我还不会!
题意:选一个初始值k,每次从待选的数字中选一个频度大于等于k的安排给k,之后k翻倍,求k们的总和的最大值。
枚举k,至多枚举到最多的待选数字频度n。
每次二分查找lower_bound(剩余待选的频度,k),安排最小的给它,直到返回end容器。复杂度至多logn。
F1 *2100 破dp居然难度2100,我觉得F2斜率优化才值2100难度吧?
题意:每个连续长为k的区间至少选一个,总共选x个,求最大值。
我当时写的是dp[i][j][k](此k非彼k),从前i个数里以j结尾的已选了k个的最大值,先初始化为负无穷-1e18(就不用判合法了)
初始条件
dp[0~k][0~i][1]=a[j]
转移是
dp[i][j][k]=max:dp[i-k+1~i-1][i~j-1][k-1]
其实第一维没有必要,直接dp[j][k]就可以了,你看上式的j和i基本都是贴一起的,再说我也没规定要从前i个选,只要人为确定i作为dp方向,每次更新dp[j][k]就可以的。
F2 *2300 据说是斜率优化dp,感觉也可以上线段树直接找区间最大值。还没试过。