AGC017F

题面

给定一个 \(n\) 层的三角形图,第 \(i\) 层有 \(i\) 个节点。

\(i\) 层的节点,从左到右依次标号为 \((i, 1),(i, 2), . . . ,(i, i)\),你需要从 \((1, 1)\) 往下画 \(m\) 条折线。你可以从 \((i, j)\) 画到 \((i + 1, j)\) 或者 \((i + 1, j + 1)\)

现在有一些限制:

  • 保证第 \(i\) 条折线的任何一个位置必须不能处在第 \(i − 1\) 条折线的左侧
  • 给出 \(k\)\((a_i,b_i,c_i)\),表示第 \(a_i\) 条折线处于位置 \((b_i, j)\) 时,下一小段必须走向 \((b_i + 1, j + c_i)\)

询问不同的折线画法的方案数,对 \(10^9 + 7\) 取模。

数据范围:\(n,m\le 20\)

题解

肯定是往状压上去想,发现按三角形从上到下去状压根本不好做,而且发现一条线走的过程正好可以表示成长度为 \(n\)\(01\) 串,所以可以考虑设 \(f_{i,S}\) 表示第 \(i\) 条线走的状态是 \(S\) 的方案数。

注意到对于折线 \(S\) ,一条折线 \(T\) 合法当且仅当 $\forall\ i\in[1,n],\sum_{j=1}^i S_j\le\sum_{j=1}^i T_j $ 。

所以就有 \(O(m4^n)\) 的做法。

考虑一个比较常见的优化:我们不需要枚举 \(T\) ,而考虑依次枚举 \(T\) 的每一位,判断合法可以通过记录前缀和而完成,这样就可以设 \(f_{i,j,k,S}\) 表示考虑到第 \(i\) 条折线,枚举了 \(T\) 的前 \(j\) 位,\(\sum_{j=1}^i T_j-S_j\) 的答案,\(T\) 的前 \(j\) 位和 \(S\) 的后 \(n-j\) 位是什么。

这样就是 \(O(mn^22^n)\) 的,还是过不去。

现在还要继续优化一维,其他的根本无从下手,于是考虑优化掉 \(k\) 那一维。

我们来手玩一下转移,考虑如果现在 \(k=0\)

  • \(S_{j}=1\) ,那么我们只能让 \(T_j=1\)

  • \(S_j=0\)

    • \(T_j=0\) ,没有任何改变。

    • \(T_j=1\) ,本来这个时候是让 \(k=1\) 的,但现在我们想去掉 \(k\) ,考虑什么时候 \(k\) 会减一,就是当下一个 \(S_j=1\) 的时候。

      那么我们直接让下一个 \(S_j=1\rightarrow 0\) ,惊奇的发现,这样和 给 \(k+1\) 的效果是等价的!并且 \(S\) 后面 \(n-j\) 位对接下来 \(i+1\) 条折线的选择根本没有影响,所以对后面也是没有影响的。

这样我们就成功优化掉了 \(k\) 那一维,复杂度是 \(O(mn2^n)\) 的。

启发

  • 轮廓线dp的时候可以根据合法条件的判断直接在状态上做更改!
posted @ 2022-07-11 17:01  qwq_123  阅读(27)  评论(0编辑  收藏  举报