SquareSubsequence

Square Subsequence

一眼 DP

首先状态:\(f[i][j]\) 表示第一个 \(T\)\(1\sim i\) 中,第二个 \(T\)\(i+1\sim j\),然后必选 \(s[i],s[j]\) 的方案数。

可以想到基本的转移 \(f[i][j]+=f[a][b](a<i,i<b<j,s[a]=s[b])\)

当然这样会有重复,样例 2 就给了我们启示: zzz 中不管是那两个 z 匹配都只算一种。

那应该怎么办呢?

遇到这种情况,我们通常会给 DP 做一些特殊的性质。

我们这里规定,只有 \(TT\) 都尽量靠前,才计数,如样例 1 ababbaba,只计算 1234 四个位置的 abab,不计算其他任何的 abab

为了实现这一目的,我们需要记录一个数组 \(nxt[i][c]\) 表示从 \(i\sim n\) 第一个 \(c\) 出现的位置(规定 \(n+1\) 表示不存在)。

接下来就是转移。

我们首先考虑枚举一个分界点 \(k\)(这里保证 \(s[k]\) 被选择,注意对于每个 \(k\),每次 \(f\) 数组需要清空),保证 \(1\sim k-1\) 为第一个 \(T\)\(k\sim n\) 为第二个。然后首先得保证左边的 \(T\)\(s[k]\),可以用 nxt,然后标记那个状态为 \(1\)。接下来,枚举 \(1\sim k-1,k\sim n\),进行向后转移,判断范围是否正确。

code

posted @ 2023-06-18 13:44  wscqwq  阅读(24)  评论(0编辑  收藏  举报