我好菜啊
又双叒叕垫底辣
其实题目并不难
不光是度把握不好,而且T1,T2还是没有抓住题目的性质,(性质才是关键啊)
(其实大部分题不会做都是因为没有抓住题目的性质。。)
T1:
一个显而易见的结论是,两人一定从S中选择最大的一个取走
一个显而易见的复杂度是O(NK)
一个显而易见的暴力是模拟一遍用堆维护O(NKlogN)
另一个显而易见的暴力是用一个桶维护出现次数和最大值,然后暴力更新mx.O(N^2K)
没有别的办法了吗?
桶的mx指针往下跳是O(N),因为可能往上跳,
我们其实并不需要桶的指针来回跳,
如果新加入的值大于mx,那么一定就取这个值,对mx无影响
而小于mx,就放进桶,然后取出一个mx。然后mx向下走更新
这样,mx单调递减。
O(NK)+卡常
其实这个题就是优化一下暴力,排除冗余的更新
T2:
考虑树形dp
链竖直,所以考虑f[x]表示x根子树,x作为一条链的上端最大值
O(N^2)可以dfs套dfs
不暴力dfs的话,要考虑能否在儿子链的基础上接上自己
但是直接做不行的,因为最大最小值都不知道是多少。
如果最大最小值在特殊位置,那么会很容易处理。
经过一些观察发现
一条链一定两端最大最小值,而且中间单调!
否则劈成两半或多半一定更优!
所以我们dp转移的时候,不用找整个链
dp[x][0/1]表示x为根的子树,x作为链的顶端是最大值还是最小值的最大总和
要么不作为开端,要么和子树连接。
由于本身是最值,儿子本身也是最值,所以可以直接把贡献得到。
O(N)
启发我们:
当题目数据范围和算法有了矛盾的时候,第一反应不是套高级数据结构暴力搞一搞
而是应该尝试发现题目的性质,简化不必要的过程
这两个题都是在题目性质的基础上优化暴力。
上次的主席树维护AC自动机儿子指针也是这样。
以后还是要打起精神,努力发掘题目性质,尝试换一种思维等等。
这比套用高级算法有意义的多。