📅  最后修改于: 2023-12-03 15:28:47.520000             🧑  作者: Mango
在硬笔字的世界里,有许许多多的开头和结尾,这就需要一把切割的钥匙,来将文字拆分成一个一个的“门片”。给你一个长度为 $n$ 的只包含字母 's'
和 't'
的字符串,你需要求出在所有可能的 $2^n$ 个“门片”中,字母 s
的数量减去字母 t
的数量最大的值,即:
$$ \max_{S\subset [1,n]}{\text{count_s}(S)-\text{count_t}(S)} $$
其中 $\text{count_s}(S)$ 表示仅考虑字符串 $S$ 中的字符,'s'
的数量减去 't'
的数量所得到的结果。
例如,对于字符串 'tsts'
,有 $2^4$ 个“门片”,其中 $\text{count_s}({1,3,4})-\text{count_t}({1,3,4})=2$ 是最大的。
输入格式:
s
和 t
。输出格式:一个整数,即字母 s
的数量减去字母 t
的数量的最大值。
4
tsts
2
2
tt
-2
这道题等价于求字符串 $S$ 的一个子序列,即子序列中的字符 's'
的数量减去字符 't'
的数量最大。对于这种求子序列问题,我们首先可以想到使用动态规划来解决。
我们可以定义状态 $f(i,x)$ 表示前 $i$ 个字符中选出的某个子集(用 $x$ 来表示)中字符 's'
的数量减去字符 't'
的数量,那么状态转移方程为:
$$ f(i,x)=\begin{cases} 0 & i=0,x=\varnothing \ f(i-1,x)+1 & S[i]=\text{'s'}, i\neq 0 \ f(i-1,x)-1 & S[i]=\text{'t'}, i\neq 0 \ \max_{y\subset x}f(i,y) & i \neq 0,x\neq \varnothing \end{cases} $$
其中第一个情况表示,当 $i=0$ 且 $x=\varnothing$ 时,表示一个空的子集,对其求解是约定其值为 $0$ 。
第二个和第三个情况表示,当前位置字符为 's'
或 't'
,根据其特性分别加入或减去符号,求解更大的值。
第四个情况表示,当前位置不选,也就是子集不加入当前位置字符,那么转移就可以直接使用上一个位置,但由于状态是包括字符集 $x$ 的变量,那么这里需要逐一枚举所有子集,再求最大值。
最终答案就是 $\max_{x\subset [1,n]}f(n,x)$ ,即在所有的合法子集中求得最大的结果。
时间复杂度:$O(3^n n)$
参考代码: