[NOI2017]泳池(历史遗留问题)

一、题目

点此看题

二、解法

我们可以做一下问题的转化,求出正好等于 k k 的就等价于求出 k \le k 减去 < k <k 的情况。

0x01 预处理

有一个根本想不到 d p dp ,由于每一个格子安全或者不安全的概率是一样的,所以位置就没有这么重要了,我们定义 d p [ i ] [ j ] dp[i][j] 为最大矩阵大小为 i × ( j 1 ) i\times (j-1) ,并且在 j j 处被截断了,我们可以写出如下转移:
{ d p [ i ] [ j ] = 0 i × j > k d p [ i ] [ j ] = t = 1 i ( p = j + 1 d p [ t 1 ] [ p ] ) × ( p = j d p [ i t ] [ p ] ) o t h e r w i s e \begin{cases} dp[i][j]=0 & i\times j>k\\ dp[i][j]=\sum_{t=1}^{i} (\sum_{p=j+1}^\infty dp[t-1][p])\times (\sum_{p=j}^\infty dp[i-t][p]) & otherwise \end{cases} 解释一下为什么第一个柿子要从 i + 1 i+1 开始枚举,因为同一行可能有多个叉,所以我们只能然后面的去统计前面的方案。显然上式可以用后缀和优化,我们设 d p s [ i ] [ j ] = p = 1 d p [ i ] [ p ] dps[i][j]=\sum_{p=1}^\infty dp[i][p] ,柿子就可以写成这样:
d p [ i ] [ j ] = t = 1 i d p s [ t 1 ] [ j + 1 ] × d p s [ i t ] [ j ] dp[i][j]=\sum_{t=1}^i dps[t-1][j+1]\times dps[i-t][j] 真正有用的状态数只有 k log k k\log k 个(考虑 k + k 2 + . . . . . k+\frac{k}{2}+..... 的大小),转移复杂度 O ( k ) O(k) ,处理出 d p dp 数组总共的复杂度是 O ( k 2 log k ) O(k^2\log k)

0x02 海岸线

得到 d p dp 数组以后,海岸线就好处理多了,我们定义 f [ i ] f[i] 为处理到了 i i 处,在 i i 处安放障碍的概率,则转移为:
f [ i ] = j = 1 k f [ i j 1 ] × d p s [ j ] [ 2 ] f[i]=\sum_{j=1}^k f[i-j-1]\times dps[j][2] 上式显然能用矩阵快速幂解决,时间复杂度 O ( k 3 log n ) O(k^3\log n)

上式是一个常系数齐次线性递推,直接套板子,可以优化到 O ( k 2 log n ) O(k^2\log n)

咕咕咕
发布了192 篇原创文章 · 获赞 12 · 访问量 3340

猜你喜欢

转载自blog.csdn.net/C202044zxy/article/details/103676764
今日推荐