当前位置: 首页 > news >正文

题解:uoj748 机器人表演

每步都很厉害的一个题。

题意:给出一个不一定匹配的括号序列,求其和任意给定长度 \(t\) 的合法括号序列合并后有多少种本质不同的串。\(n,t\le 300\)

做法:

首先考虑判定怎么做,我假设有原串 \(s\),我如何判定一个串 \(t\) 可以被分解为 \(s\) 和一个合法括号串呢?设 \(f_{i,j}\) 表示目前已经匹配到了 \(s_i, t_j\),是否可行,\(a,b\) 分别代表两个串括号序列的前缀和,左括号为 \(1\) 右括号为 \(-1\)。有转移式:

\[f_{i, j}\rightarrow f_{i+1,j+1}(s_i=t_j) \]

\[f_{i,j}\rightarrow f_{i,j+1}(a_i\le b_{j+1}) \]

第一种转移显然,第二种转移其实是我选择用括号串上的一位去补,但是因为我往 \(s\) 中塞这个括号串之后,前缀和是不会小于我原串的前缀和的,所以需要 \(a_i\le b_{j+1}\)

那么怎么计数?直接用 dp of dp 的套路,\(dp_{i,j,V}\) 表示已经填好了 \(t\) 的前 \(i\) 位,\(b_i=j\),同时我们把 \(f_{?,j}\) 压成一个二进制串作为 \(V\),这样可以做到 \(2^nn(n+t)^2\)

然后感觉没有什么优化空间了。但是经过观察或者打表会发现,我们其实只需要管 \(V\) 的最高位即可,我们来证明这个结论。

先有一个很显然的观察,如果 \(f_{i,j}=1\),那么 \(a_i\le b_{j}\),考虑转移过程易得。

考虑目前 \(dp_{i,j}\) 的最高位为 \(k\),若加入新的一位为 \(x\),有:

  • \(s_{k+1}=x\),那么显然可以直接匹配,转移贡献 \(k+1\)

  • 否则如果 \(x\) 为左括号或 \(a_k<b_{i}\),显然会满足 \(a_k\le b_{j+1}\),贡献为 \(k\)

  • 否则如果 \(x\) 为右括号且 \(a_k=b_{i}\),那下一位就匹配不了了。我们会说明会变成 \(k'=\max\limits_{t<k,a_t<a_k} t\)。首先说明这个串是合法的,因为 \(s[k'+1,k]\) 这一段其实是一个合法的括号前缀,否则会有更大的 \(k'\),所以我们可以得出 \(f_{k',i}\) 是合法的,这样就可以把这个匹配进去了。同时也很容易说明更大的 \(k'\) 不行。

这样我们就可以只记 \(k\) 而不用记 \(V\) 了,复杂度优化到 \(O(n^3)\)

然后官方题解评论区提到了另一种理解方法,就是我考虑贪心地进行匹配 \(s, t\),每次不能匹配就给括号序列解决,但是这样同样会遇到出现右括号而左括号不足的情况,这样就需要我们类似反悔贪心,回退到上一个前缀和小于当前位置的位置,这个串刚好就是开头一个左括号加上一个合法括号序列,可以再加一个右括号。正确性由上述证明得到也是对的。按照这个贪心过程设计 dp 也可以通过。

因为下面这个做法常数小一点写了下面这个做法:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 305, mod = 998244353;
int dp[maxn][maxn][maxn], pre[maxn], n, t;
string s;
signed main() {cin >> n >> t >> s; s = ' ' + s;for (int i = 1; i <= n; i++) {int s1 = 0;for (int j = i; j >= 1 && s1 >= 0; j--) {s1 += (s[j] == '1' ? 1 : -1);pre[i] = j;}if(s1 >= 0)pre[i] = 0;}dp[0][0][0] = 1;for (int j = 0; j <= t; j++)for (int k = 0; k <= j; k++) {for (int i = 0; i <= n; i++) {if(!dp[i][j][k])continue;if(i < n) dp[i + 1][j][k] = (dp[i + 1][j][k] + dp[i][j][k]) % mod;if((i == n || s[i + 1] == '1') && j < t)dp[i][j + 1][k] = (dp[i][j + 1][k] + dp[i][j][k]) % mod;if((i == n || s[i + 1] == '0') && k < j)dp[i][j][k + 1] = (dp[i][j][k + 1] + dp[i][j][k]) % mod;if((i == n || s[i + 1] == '0') && k >= j) {int tp = (i - pre[i] + 2) / 2;if(tp + j > t || pre[i] == 0)continue;dp[pre[i] - 1][j + tp][k + tp] = (dp[pre[i] - 1][j + tp][k + tp] + dp[i][j][k]) % mod;}}}cout << dp[n][t][t] << endl;return 0;
}
http://www.zskr.cn/news/31302.html

相关文章:

  • 2025 年混合机,强力混合机厂家最新推荐,产能、专利、环保三维数据透视!
  • Linux 自动输入 Enter 键
  • Voyage系列3: 技巧与提示
  • 完全开源!一款基于 SpringBoot + Vue 构建的社区平台!
  • 【一步步开发AI运动APP】十二、如何进行运动开始前的站位预检,提升用户体验
  • 2025年10月品牌认证机构推荐:权威榜单对比五强优劣
  • 解析 MySQL 与 KingbaseES 字符串排序规则差异
  • 2025 年最新推荐 PPT 生成软件排行榜:权威协会测评 + AI 备案技术加持,3500 万用户信赖之选全面解析
  • 数据结构——LinkedList和链表 - 实践
  • 10 25
  • 2025 年青岛点焊机厂家最新推荐榜,聚焦技术实力与市场口碑深度解析螺母/自动/螺栓/储能/汽车零部件点焊机厂家推荐
  • 日记14
  • 三年级小学生日记范文
  • easy-query暴打efcore(包括其他所有orm),隐式Group看我如何在子查询做到极致的性能天花板
  • 完整教程:深入理解-自然拼读(英语)
  • 能在0.02秒内找到最优解的华容道程序
  • Sparkle签名检查绕过漏洞分析
  • dataGridView 控件表格颜色交替设置
  • 2025年10月洗地机产品推荐榜:价格与性能全面对比
  • 读AI赋能11自由认知
  • SAM2 图像分割(3)鼠标选择多框 摄像头实时分割显示 - MKT
  • Semantic-SSAM 是“一切多细都行,还能给标签”​​ - MKT
  • P1679 神奇的四次方数
  • 20232419 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 详细介绍:分布式任务事务框架设计与实现方案
  • 事件日志查看Windows安装软件情况
  • 凭借Ubuntu和i.MX 6ULL开发板构建网络共享
  • 【CI130x 离在线】FreeRTOS的流缓冲(StreamBuffer)
  • 循环
  • RT-Thread Nano源码浅析