csps区间dp

加分二叉树

我们可以枚举中间这个 k 的位置,然后分别递归计算左右子树,这就让我们想到这是一个和区间有关的,我们可以用区间dp来解决。

\(f[i][j]\) 表示 i, j 这个区间的最大分值。用一个很板子的区间dp就可以解决了。

至于求前序遍历,我们也只需要通过递归然后枚举中间的根,第一个满足最大值的就是字典序最小的,这样就可以解决了。

能量项链

破环成链,然后很明显能看出来这是一个区间dp,直接套板子。(貌似需要开long long)

矩阵取数游戏

由于每一层之间都是相互独立的,所以我们可以对于每一行进行区间dp,然后存一个 res 去累加每一行的分值。

对于每一次的 \(2 ^ i\) 我们可以采用快速幂来解决。

但是由于最后结果可能很大,我们要注意,要么开高精度,要么开__int128

括号序列

属于是区间dp + 状态机模型了。(

我们可以对一个很长的字符串进行一步一步的拆解。

我们这样子定义状态:

  1. \((\dots)\) 表示左右两边有括号,然后中间是一堆 *,这个括号是单独的。
  2. \(()()()()\) 一堆括号并列。
  3. \(****()\) 前面一堆星,后面跟个超级括号。
  4. \(()**()**\) 前面是单独的或者并列的,后面是一堆星。
  5. \(()()(\dots)\) 后面是星号。

\[f[l][r][0] = \sum_{i=0}^{5} f[l][r][i] \]

\[f[l][r][1] = f[l][r][0] * (f[l][r][0] + f[l][r][1] + f[l][r][3] \]

\[f[l][r][2] = f[l][r][2] \]

\[f[l][r][3] = \sum_{i=0}^{1} f[l][r][i] * f[l][r][2] \]

\[f[l][r][4] = \sum f[l][r][2] * (f[l][r][1] + f[l][r][0]) \]

最后的结果要么是并列的(2),要么是单独的(1)。二者相加就是答案了。

posted @ 2023-10-02 22:37  carp_oier  阅读(22)  评论(0)    收藏  举报