YACS 2023年5月月赛 甲组 T3 铺砖问题 题解
感谢 易敬然 大佬在 三铺地砖 中教会了我插头 DP,我看着他的题解慢慢写出了这题。
我们来考虑在某个位置放
在叉叉的位置放一个
此时就能设出状态了,顺次填入砖块。考虑到点
下面来看转移了,我们从上到下,每行按照从左到右依次转移。一共有三种(注意,我们不在红橙色区域外填,那样会填到蓝色区域里,我们将会在顺次考虑到蓝色区域时再算):
第一种:
需要注意的是,画叉叉的是要填的,必须要被填,值为
如果画叉叉的是
这种其实就是刚刚说过的,填完后顺次转移,橙色块(要考虑的块)向右移一个,可以转移到这种状态:
其中橙色方块左边的红色方块是
第二种:
横着填,注意,标 "0" 的格子必须在状态中是 "0"。因为我们转移到下个状态时,它就成了黄色格子,是已经填完的了。
特判同一,填完变成:
第三种:
摆烂,啥都不填,但是标
最后还会爆空间,滚动一下就行,时间复杂度:
#include <iostream> using namespace std; int n, m, now; int t, cnt; int st[1 << 18], map[19][19]; int f[2][1 << 18]; const int mod = 1000000007; char c; int main () { cin >> n >> m; f[0][0] = 1;//都填完了,方案数为 1 for (int i = 0; i <= n; i ++) for (int j = 0; j <= m; j ++) map[i][j] = 1; for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { cin >> c; if (c == '*') map[i][j] = 0; } } for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { cnt = 1; st[1] = 0; for (int k = m; k >= 1; k --) {//判断哪些能填哪些不能填。 if ( (j > k && map[i][j - k]) || (j <= k && map[i - 1][j + m - k]) ) { int sz = cnt; for (int l = 1; l <= sz; l ++) { st[l + sz] = st[l] << 1; st[l] = st[l] << 1 | 1; } cnt *= 2; } else for (int l = 1; l <= cnt; l ++) st[l] <<= 1; } for (int k = 0; k < (1 << 18); k ++) f[(now + 1) & 1][k] = 0; for (int k = 1; k <= cnt; k ++) {//转移 int state = st[k], pos; if (f[now & 1][state] == 0) continue; if (i != 1 && (state & (1 << m - 1) ) && map[i][j] != 0 && map[i - 1][j]) {//1 是没被填的,0 是填过不用填的 pos = state;//竖着填 pos ^= (1 << m - 1); pos <<= 1; f[(now + 1) & 1][pos] += f[now & 1][state]; if (f[(now + 1) & 1][pos] >= mod) f[(now + 1) & 1][pos] -= mod; } if (j != 1 && (state & (1 << m - 1) ) == 0 && (state & 1) && map[i][j] != 0 && map[i][j - 1]) {//横着填 pos = state; -- pos; pos <<= 1; f[(now + 1) & 1][pos] += f[now & 1][state]; if (f[(now + 1) & 1][pos] >= mod) f[(now + 1) & 1][pos] -= mod; } if ( (state & (1 << m - 1) ) == 0) { pos = state; if (map[i][j] == 0) pos <<= 1; else pos = pos << 1 | 1; f[(now + 1) & 1][pos] += f[now & 1][state]; if (f[(now + 1) & 1][pos] >= mod) f[(now + 1) & 1][pos] -= mod; } } now ++; } } cout << f[now & 1][0]; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异