2021年蓝桥杯第十届软件类省赛 c++A组 第一场(口胡题解) 未完成
好吧虽然上次的还没完成但我又来口胡了_(:з」∠)_
不知道有没有简单公式,但直接暴力模拟应该也没有什么问题吧
一共四百多个点而已,可以直接暴力找到所有可能直线然后去重。去重我感觉搞个结构体sort一下然后扫一遍就好了
乍一看以为是个DP
仔细一想题意应该是给定\(n\),找 满足\(abc=n\)的点对\((a, b, c)\)的个数。
也就相当于找到\(n\)的所有质因数,分成\(3\)堆,每堆不同,求方案数。
\(n\)的质因数个数最多就\(logn\)个,所以这里直接暴力找找就好
统计的话目前是两种想法:
1,直接对于所有质因数统计,再对相同质因数去重
\(t(i)\)表示第\(i\)种质因数的个数
2,对不同质因数分开统计
具体统计时用的都是插板法
看起来暴力建边暴力跑也没什么问题的样子
看起来可以状压搞搞的样子
看上去直接DP就好,\(f[i]\)表示重量\(i\)是否可以被表示,注意由于砝码可以放两边,所以砝码权值可正可负,转移的时候注意一下,应该可行?
看上去是博弈论,我对博弈论一无所知……
注意到一棵树内部对子树怎么重新组合,其实不会影响它父亲和兄弟。
它的兄弟会在父亲的支配下被放入这棵树的右侧。
所以我们可以尝试树形DP
\(f[i]\)表示以\(i\)为根的子树重新组合后的最大高度。那么考虑一个贪心的做法。
按\(f[i]\)从小到大排序,把高的子树接在矮的子树下面。
为什么这样一定最优?
如果一个子树比它兄弟高,而你把它兄弟接在它右儿子的位置,那这个子树的高度不会被扩展,因为它兄弟这个分支的最大深度就是它兄弟原本深度 + 1,是小于等于这个子树深度的。
所以我们要尽量保证子树比它兄弟低,才把它兄弟放在右儿子的位置。
这样复杂度大概是\(O(n + \sum{m(i)logm(i)})\), \(m(i)\)为节点\(i\)的子节点个数,所以复杂度约为\(O(n + nlogn)\)
分别考虑左右括号补全。
对于一个未匹配的左括号,我们在它右侧补右括号使其合法,由于我们补全的右括号一定是和这个左括号匹配的右括号,所以不会影响其他未匹配右括号的匹配情况
右括号同理。
因为补全左右括号过程相对独立不冲突,所以我们先考虑将序列中所有左括号变合法,再考虑使所有右括号变合法
我们先来考虑本质不同这个点。
本质相同的补全造成的重复无非就是几个右括号排在一起可以交换顺序之类的。
所以我们考虑只在左括号右侧插右括号,可以插入多个右括号
从左向右DP, 令f[i][j]表示DP到i位, 已经补全了j个括号
i这一维可以滚掉,因为第二维是大的数用到小的数,所以从后向前枚举。
考虑到新f[j]要求的其实是个前缀和,所以可以每次统计一下前缀和,优化一下,这样就是\(O(n^2)\)的。
然后对于右括号也是类似的做法,最后两次DP的答案相乘就是最终答案。
纯属口胡,没验证正确性_(:з」∠)_