LOJ #2304. 「NOI2017」泳池
题目叙述
\(1001\times n\) 的网格图,每个格子有 \(p\) 的概率是不危险的。求最大的不危险的格子组成的底边与整个网格底边重合的最大长方形面积恰好为 \(k\) 的概率是多少。
题解
先差分一步,改成求最大值 \(\le k\) 的概率。
有一种想法是从左往右 dp ,但很快发现我们需要维护一个单调栈(就是说 dp 状态里记录一个单调栈),不可行。
因此从下向上填。设 \(f_{i,j}\) 表示底边长度为 \(i\) ,面积 \(\le j\) ,这块区域往上的面积 \(\le k\) 的概率是多少。
但是这个 dp 好像莫名其妙的原因,状态数量好像并不直观。
题目要求 dp 的东西的本质结构其实是一个类似于笛卡尔树的东西。一般来说状态是设 \(f_{i,j}\) 表示底边长度为 \(i\) ,高度为 \(j\) ,高度 \(\ge j+1\) 的那些位置都符合条件的概率是 \(f_{i,j}\) 。
转移只要枚举从左到右第一个危险的格子就可以了。
\(f_{h,w}=\sum_{i=1}^wf_{h+1,i-1}f_{h,w-i}(1-p)p^{w-i}+f_{h+1,w}p^w\)
下一步是你对这个dp算式/看着原图的符合条件的填法进行观察。你会发现,原图最后一排相邻两个危险的方格之间的距离不能超过 \(k\),否则一定不满足条件。由此可以导出 \(f_{h,w}\) 在 \(h=0\) 的时候转移只需要用到 \(f_{1,1}\sim f_{1,k}\) 。
然后发现在 \(f_{0,i}\) 层面上看,就是一个关于 \(i\) 的常系数齐次线性地推。套上板子即可。
简单介绍一下常系数齐次线性递推:比如要计算斐波那契数列的第 5 项,其实就是 \(x^5\mod (x^2-x-1)\) 得到的结果加以处理。总之试一试就可以理解他的本质。
总结
- 笛卡尔树形状的动态规划可以以下面的大小为状态。
- 有些时候先做第一步就可以起到一些作用。
- 分析一下算法主要复杂度花在哪也可以发现第一步是最大的。
- 优化一个东西的时候,可以先模拟模拟他的过程。