DP做题记录
ICPC-22-JN C(62/504)
dfs的同时DP,u由fa转移,问题在于求同层兄弟选i个组成size和为j的方案数:这个暴力是\(O(n^4)\)的,一开始考虑了预处理前后缀再拼起来,然而拼起来的复杂度更高;想到先所有儿子做一遍再回退DP,但又觉得银牌DP题用不到这么高级的东西,往其它DP方式/树的性质优化考虑了一会,并没有可行的做法。
只能再考虑回退DP,发现这个转移很简单,于是按反方向枚举,减掉转移过来的东西即可。
ICPC-21-MC H(1/102)
很巧妙的数数方式
原本想暴力枚举相邻的两个数算贡献,但这个树上合法且两点相邻的排列数不太好算,要硬算至少得\(O(n^5)\),前途黑暗(一开始以为预处理一下可行,写了一堆才发现不对劲)
暴力算贡献的垃圾之处在于,虽然枚举完之后都是一样的问题,但这种方式的枚举又是不可避免的。
考虑相邻两数差的绝对值
这个比较讨厌的东西:枚举效率不行,又不是一个好DP算的式子;考虑把这个贡献拆开——就是把两点距离贡献到其中的每个整点上,具体来说,对相邻的两个数x<y,这个贡献y-x拆成在枚举\(x,x+1,...,y-1\)这些断点时都被算一次(枚举每个数时,不大于的标0,大于的标1,贡献就是01段数)。于是对全局枚举这个断点,然后对树计算所有合法排列的01段数,这可以用比较暴力的\(O(n^2)\)DP算出(思路简单,但还是有些细节,代码略长)
tip:
这种题过样例后wa建议写对拍,因为自己不好造hack,且暴力好写+好帮助验证,写个对拍很快就发现错误了(虽然在if语句里加continue想退出if
这种错误有点弱智,但静态有时候真不好找)
感觉离场上AC这种题还是有些距离,不过学到这种处理绝对值的方式还是很有收获的。