链接
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;
}