题目地址:
https://www.acwing.com/problem/content/description/1886/
奶牛贝茜在她最喜欢的牧场中发现了一块石碑,上面刻有神秘的碑文。碑文的文字似乎来自一种神秘的古代语言,可看作一个只包含C,O,W
三种字符的字符串。尽管贝茜无法解密该文字,但是她很欣赏C,O,W
按顺序构成她最喜欢的单词COW
。她想知道COW
在碑文中一共出现了多少次。她不介意C,O,W
之间是否存在其他字符,只要这三个字符按正确的顺序出现即可。她也不介意多个不同的COW
是否共享了一些字符。例如,COW
在CWOW
中只出现一次,在CCOW
中出现两次,在CCOOWW
中出现八次。
给定碑文中的文字,请帮助贝茜计算COW出现的次数。
输入格式:
第一行包含
N
N
N。
第二行包含一个长度为
N
N
N的字符串,其中只包含字符C,O,W
。
输出格式:
输出给定字符串中COW
作为子序列(不一定连续)的出现次数。
数据范围:
1
≤
N
≤
1
0
5
1≤N≤10^5
1≤N≤105
设
f
[
n
]
[
k
]
f[n][k]
f[n][k]为是字符串
s
s
s的前
n
n
n个字母里,COW
的前
k
+
1
k+1
k+1个字母的前缀作为子序列的出现次数。那么,如果
s
[
n
]
=
′
C
′
s[n]='C'
s[n]=′C′,则
f
[
n
]
[
0
]
=
f
[
n
−
1
]
[
0
]
+
1
f[n][0]=f[n-1][0]+1
f[n][0]=f[n−1][0]+1;如果
s
[
n
]
=
′
O
′
s[n]='O'
s[n]=′O′,则
f
[
n
]
[
1
]
=
f
[
n
−
1
]
[
1
]
+
f
[
n
−
1
]
[
0
]
f[n][1]=f[n-1][1]+f[n-1][0]
f[n][1]=f[n−1][1]+f[n−1][0];如果
s
[
n
]
=
′
W
′
s[n]='W'
s[n]=′W′,则
f
[
n
]
[
2
]
=
f
[
n
−
1
]
[
2
]
+
f
[
n
−
1
]
[
1
]
f[n][2]=f[n-1][2]+f[n-1][1]
f[n][2]=f[n−1][2]+f[n−1][1]。由这些递推式,可以在程序中用三个变量记录
f
[
n
]
[
0
,
1
,
2
]
f[n][0,1,2]
f[n][0,1,2],然后一路递推过去即可。代码如下:
#include <iostream>
using namespace std;
long n, f[3];
string s;
int main() {
scanf("%ld", &n);
cin >> s;
for (auto &ch : s) {
if (ch == 'C') f[0]++;
else if (ch == 'O') f[1] += f[0];
else f[2] += f[1];
}
printf("%ld\n", f[2]);
return 0;
}
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。