题目:给定一个字符串,求子序列 “cwbc” 出现的次数
思路:动态规划
令 dp[i][j] 表示前 i 个字符中匹配了字符串 “cwbc” 中前 j 位(j = 1,2,3,4)的个数。
转移方程:
dp[i][1] = ( dp[i - 1][1] + ( s[i] == ‘c’ )) % Mod
dp[i][2] = ( dp[i - 1][2] + ( s[i] == ‘w’ ) * dp[i - 1][1] ) % Mod
dp[i][3] = ( dp[i - 1][3] + ( s[i] == ‘b’ ) * dp[i - 1][2] ) % Mod
dp[i][4] = ( dp[i - 1][4] + ( s[i] == ‘c’ ) * dp[i - 1][3] ) % Mod
此时内存会超标,使用滚动数组优化开销:
dp[1] = (dp[1] + (s[i] == ′ c′)) % Mod
dp[2] = (dp[2] + (s[i] == ′ w′) ∗ dp[1]) % Mod
dp[3] = (dp[3] + (s[i] == ′ b′) ∗ dp[2]) % Mod
dp[4] = (dp[4] + (s[i] == ′ c′) ∗ dp[3]) % Mod
#include <bits/stdc++.h>
using namespace std;
#define MOD 1000000007
#define MAXN 100005
typedef long long ll;
ll dp[5];
int main()
{
memset(dp, 0, sizeof(dp));
string s;
cin >> s;
int n = s.length();
for (int i = 1; i <= n; ++i)
{
s[i] = tolower(s[i]);
dp[1] = (dp[1] + (s[i] == 'c')) % MOD;
dp[2] = (dp[2] + (s[i] == 'w') * dp[1]) % MOD;
dp[3] = (dp[3] + (s[i] == 'b') * dp[2]) % MOD;
dp[4] = (dp[4] + (s[i] == 'c') * dp[3]) % MOD;
}
cout << dp[4] << endl;
return 0;
}