CodeForces 1426F. Number of Subsequences
链接
https://codeforces.com/contest/1426/problem/F


题意
给定一个含有\(abc?\)的字符串,\(?\)可能是\(abc\)中的任意一个,求所有可能的无\(?\)字符串中,子序列\(abc\)出现的次数.
思路
首先我们可以考虑单纯的无\(?\)情况下的dp:
\(dp[i][1]\)表示当前情况下a的数量。
\(dp[i][2]\)表示当前情况下ab的数量。\(dp[i][2]=dp[i-1][2]+dp[i][1]\)
\(dp[i][3]\)表示当前情况下abc的数量。\(dp[i][3]=dp[i-1][3]+dp[i][2]\)
除此之外,因为会有\(?\)的出现,我们可以知道每增加一个\(?\),那么你的序列数量就会\(*3\)。所以对于\(?\)的情况,举个例子吧,我们要处理\(a\)的数量,那么就是前面多少个序列全部堆起来,再加前面序列数/3,即可得到当前情况下\(a\)的数量,b,c同理
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
ll dp[4];
int main()
{
std::ios::sync_with_stdio(false);
int n;
string s;
cin >> n >> s;
dp[0] = 1;
for(int i = 0;i < n;i++){
if(s[i] == 'c') dp[3] = (dp[3] + dp[2]) % mod;
else if(s[i] == 'b') dp[2] = (dp[2] + dp[1]) % mod;
else if(s[i] == 'a') dp[1] = (dp[1] + dp[0]) % mod;
else {
for(int i = 3;i > 0;--i) dp[i] = (3LL * dp[i] + dp[i - 1]) % mod;
dp[0] = dp[0] * 3 % mod;
}
}
cout << dp[3] << endl;
return 0;
}

浙公网安备 33010602011771号