P9197 [JOI Open 2016] 摩天大楼 / Skyscraper 思路分析
P9197 [JOI Open 2016] 摩天大楼 / Skyscraper 思路分析
朴素想法
对一个序列进行 DP,限制条件与一个位置相邻的元素相关,对总和限制;特殊点,绝对值运算和相对大小强相关,不妨从小到大考虑以减弱绝对值的影响。将限制条件加入状态,于是得到:
\[dp[i][j][k] \text{表示从小到大考虑到 $a_i$,其前驱为 $a_j$,当前总和为 $k$ 的方案数}
\]
问题分析
相邻元素包含前驱和后继,这样定义状态没有考虑后继点的影响;进一步的,这就影响到 \(a_i\) 是否会与已有元素连成一条链。
完善想法
通过分析问题所在,发现这个 DP 应和区间连通信息相关,同时对于一个点,其本身又和是否是某个区间的开头结尾有关,这样我们就得到了两条新的限制,用于替换和增强原本的 \(j\) 一维。
于是有:\(dp[i][j][k][t=0/1/2]\) 表示从小到大插入到了 \(a_i\),形成了 \(j\) 段,当前总和为 \(k\),占用了 \(0/1/2\) 个最终边界。状态复杂度 \(O(n^2m)\)。
考虑如何进行转移,类似插入 DP,看当前加入 \(a_i\) 后是否会有新段出现、旧段合并、原段扩展。
设 \(k'\) 为当前新的总和,那么有 \(k'=k+(2j-t)\times(a_i - a_{i-1})\),
- 新段出现:
(1)不占用最终边界:\(dp[i][j+1][k'][t]+=dp[i-1][j][k][t]\times (j+1-t)\);
(2)占用一个最终边界:\(dp[i][j][k'][t+1]+=dp[i-1][j][k][t]\times (2-k)\); - 旧段合并:\(dp[i][j-1][k'][t]+=dp[i-1][j][k][t]\times (j-1)\)
- 原段扩展:\(dp[i][j][k'][t]+=dp[i-1][j][k][t]\times (2j-t)\)
最终答案为 \(\sum_{l=0}^{L}dp[n][1][l][2]\),时间复杂度 \(O(n^2m)\)。

浙公网安备 33010602011771号