洛谷P1990 覆盖墙壁 题解
洛谷P1990 覆盖墙壁 题解
本题是一道非常好的递推题,请认真阅读,争取不看代码自己写出答案。
思路
我们可以设 \(f_i\) 为覆盖 \(2\times i\) 的所有覆盖方案。显然,边界条件 \(f_0\)(即没有列了,不用覆盖)和 \(f_1\)(只有 1 列,即一个 \(\text I\) 型砖块竖排)是为 1 的。可以根据最后几列的覆盖方法推导出递推式。
情况 1:1 个竖排 \(\text I\)
如图,这种情况下,可以根据 \(f_{i-1}\) 的方案数得来,前 \(i-1\) 列覆盖完毕后,只剩下 1 列,故只覆盖一个 \(\text I\) 型砖块。
情况 2:2 个横排 \(\text I\)
如图,这种情况下,类似情况 1,可以根据 \(f_{i-2}\) 的情况得来,前 \(i-2\) 列覆盖完毕后,忽略情况 1(因为已经计算过了),就只有这种情况了。
情况 3:1 个 \(\text L\)
如图,这种情况下,\(\text L\) 有一个凸起,这个凸起在上下 2 侧都有可能,所以最终的结果需要 \(\times 2\),要解决这种情况,需要考虑如下方法:
i:使用一个反向 \(\text L\) 补全缺口
如图,这种方法可以使用一个 \(\text L\) 补全凸起上方的缺口,此时已经覆盖好了 3 列,剩下的 \(i-3\) 列的方案数就是 \(f_{i-3}\) 了。
ii:使用一个横 \(\text I\) 解决缺口,再使用一个 \(\text L\) 补全新缺口
如图,这种方法使用了一个横 \(\text I\) 补全了旧缺口,却产生了一个新缺口,此时再使用一个新的 \(\text L\) 补全新缺口,剩下的 \(i-4\) 列的方案数为 \(f_{i-4}\)。
iii iv v ... 所有的解法
我们发现,似乎可以使用更多的横向 \(I\) 不断地补全旧缺口,产生新缺口,再使用横向 \(\text I\),最后用一个 \(\text L\) 补全缺口就又是一种新的方法。我们可以发现,似乎这类方法的最后方案数可以是 \(f_{i-3},f_{i-4},f_{i-5},\dots ,f_{0}\),所以,只要我们把这些所有的方案数加起来,即 \(\sum_{i=0}^{i-3}{f_i}\),就可以了。
所以,在情况 3 下,总的方案数是 \(2\times \sum_{i=0}^{i-3}{f_i}\)。
最终,我们成功推导出了 \(f_i\) 的递推式,即:
为了防止TLE
,我们不难发现其中 \(\sum_{i=0}^{i-3}{f_i}\) 的部分是可以利用前缀和来优化的,定义 \(s\) 表示 \(f\) 的前缀和,即 \(s_i=\sum_{j=0}^{i}{f_j}\)。
在调用 \(\sum_{i=0}^{i-3}{f_i}\) 时就可以直接调用 \(s_{i-3}\) 防止TLE
了。
代码
#include<bits/stdc++.h> #define endl '\n' using namespace std; const int INF = 0x3f3f3f3f; const double EPS = 1e-8; const int N = 1e6 + 5; const int MOD = 10000; int n, s[N], f[N]; int main() { cin >> n; f[0] = s[0] = 1; f[1] = 1; s[1] = 2; f[2] = 2; s[2] = 4; for(int i = 3; i <= n; i++) { f[i] = (s[i - 1] + s[i - 3]) % MOD; s[i] = (s[i - 1] + f[i]) % MOD; } cout << f[n] << endl; return 0; }
AC
记录
优化
我们其实可以通过上面的式子推出一个空间复杂度更好的递推式。
我们考虑
和
并且
化简后,得
移项,得最终递推式
代码
#include<bits/stdc++.h> #define endl '\n' using namespace std; const int INF = 0x3f3f3f3f; const double EPS = 1e-8; const int N = 1e6 + 5; const int MOD = 10000; int n, f[N] = {1, 1, 2}; int main() { cin >> n; for(int i = 3; i <= n; i++) { f[i] = (2 * f[i - 1] + f[i - 3]) % MOD; } cout << f[n] << endl; return 0; }
AC
记录 2(优化后)
本文作者:2789617221guo
本文链接:https://www.cnblogs.com/2789617221guo/p/18725150
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步