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\),进行向后转移,判断范围是否正确。