题目链接
1、dp变量
dp[len][m] 表示前len长度中,子序列各位和对3求余为m的子序列数量
2 递推公式,
1、当 (s[i] - '0') % 3 == 0时 dp[i][0] = dp[i - 1][0] + dp[i -1][0] + 1
dp[i][1] = dp[i - 1][1] + dp[i -1][0]
dp[i][2] = dp[i - 1][2] + dp[i -1][0]
2、 当 (s[i] - '0') % 3 == 1时 dp[i][1] = dp[i - 1][1] + dp[i -1][0] + 1
dp[i][0] = dp[i - 1][0] + dp[i -1][2]
dp[i][2] = dp[i - 1][2] + dp[i -1][1]
3、当 (s[i] - '0') % 3 == 2时 dp[i][2] = dp[i - 1][2] + dp[i -1][0] + 1
dp[i][0] = dp[i - 1][0] + dp[i -1][1]
dp[i][1] = dp[i - 1][1] + dp[i -1][2]
3
初始值:(以0为第一个元素位置)
dp[0][(s[0] - '0') % 3] = 1;
代码
/*
dp[len][m];
前len长度中,和对3求余的子序列数量
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 LL;
const int maxn = 1000 + 5;
const int mod = 1e9 + 7;
int dp[55][3];
int Dp(int len,const string &s)
{
memset(dp,0,sizeof dp);
dp[0][(s[0] - '0') % 3] = 1;
for(int i = 1; i < len; i++){
int m = (s[i] - '0') % 3;
dp[i][m]++;//单独一个也算一个子序列
for(int j = 0; j < 3; j++){
dp[i][j] += (dp[i - 1][j] + dp[i - 1][(j + 3 - m) % 3]) % mod;
}
}
return dp[len - 1][0];
}
int main()
{
std::ios::sync_with_stdio(false);
string s;
cin>>s;
int len = s.size();
int ans = Dp(len,s) % mod;
cout<<ans<<endl;
return 0;
}

京公网安备 11010502036488号