Description

很经典的问题 子序列可以是任意的 借用一下某小白赛的题目 在每个字符串中Cwbc作为子序列分别出现了多少次。

Solution

很经典的dp 用dp[i][j]来表示前i个字符中 匹配的字符j个数 j这个维度是子序列的长度 这题中j的长度就为4 分别为1,2,3,4
容易想到转移方程
图片说明
图片说明
图片说明
图片说明

注意方程中(s[i] =='c')*dp[i-1][j] 等于的话满足条件 才和前面一个状态相乘 因为算的是各种情况组合起来所以是相乘 答案的话很明显是dp[n][4]

正常的话这样就可以过了 但是在这题会卡空间 我们可以看到当前状态只和前一个状态有关 可以直接删除第一维 所以转移方程变为
图片说明
图片说明
图片说明
图片说明

注意取模操作

Code

#include <bits/stdc++.h>

using namespace std;

#define LL long long

const LL mod = 2000120420010122;

LL dp[5];

int main() {
  ios::sync_with_stdio(0);

  string s;

  while (cin >> s) {
      for(int i = 1;i <= 4;i ++){
          dp[i] = 0;
      }

    for (int i = 0; i < s.size(); 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] % mod << '\n';
  }
  return 0;
}