P4290 [HAOI2008] 玩具取名(区间dp,传递闭包?)
有点传递闭包的思想感觉这题(无聊倒装
首先为了便于处理,将 W,I,N,G
映射为 1,2,3,4
那么处理数据,想到可以用 传递闭包 的思想?感觉差不多,因为这道题有很多一一对应的关系,并且可以由小的对应关系得到大的对应关系
对于每次输入对应的两个字符
题目要求给定一个串
定义
引入中间值
两个小区间的第三维度?想到 一个字符总是对应两个字符,所以另外两个字符也要分别枚举,不过要能转移的条件肯定要 另外两个字符能对应
哦对了,注意边界初始化,对于区间 [i, i],它肯定能被 i 上的字符替换
忽略枚举
#include <bits/stdc++.h> #define re register int using namespace std; const int N = 210; int n, s[5], mat[N]; int g[5][5][5], f[N][N][5]; char t[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); mat['W'] = 1, mat['I'] = 2, mat['N'] = 3, mat['G'] = 4; for (re i = 1; i <= 4; i ++) cin >> s[i]; for (re i = 1; i <= 4; i ++) for (re j = 1; j <= s[i]; j ++) { string c; cin >> c; g[mat[c[0]]][mat[c[1]]][i] = 1; } string tt; cin >> tt; n = tt.size(); for (re i = 0; i < n; i ++) t[i + 1] = tt[i]; for (re i = 1; i <= n; i ++) f[i][i][mat[t[i]]] = 1; for (re len = 1; len <= n; len ++) for (re l = 1; l + len - 1 <= n; l ++) { int r = l + len - 1; for (re k = l; k < r; k ++) for (re x = 1; x <= 4; x ++) for (re y = 1; y <= 4; y ++) for (re z = 1; z <= 4; z ++) f[l][r][x] = f[l][r][x] | (f[l][k][y] & f[k + 1][r][z] & g[y][z][x]); } bool flag = false; if (f[1][n][1]) { flag = true; cout << 'W'; } if (f[1][n][2]) { flag = true; cout << 'I'; } if (f[1][n][3]) { flag = true; cout << 'N'; } if (f[1][n][4]) { flag = true; cout << 'G'; } if (!flag) cout << "The name is wrong!"; cout << '\n'; return 0; }
分类:
E 动态规划 - 区间 dp
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具