📜  门|门 CS 1996 |第 53 题(1)

📅  最后修改于: 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$ 是最大的。

输入格式:

  • 第一行为一个整数 $n$。
  • 第二行为一个长度为 $n$ 的字符串,仅包含小写字母 st

输出格式:一个整数,即字母 s 的数量减去字母 t 的数量的最大值。

数据范围

  • $1\leq n\leq 20$

样例

样例1
输入:
4
tsts
输出:
2
样例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)$

参考代码: