被3整除的子序列

题目链接

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

全部评论

相关推荐

05-12 17:00
门头沟学院 Java
king122:你的项目描述至少要分点呀,要实习的话,你的描述可以使用什么技术,实现了什么难点,达成了哪些数字指标,这个数字指标尽量是真实的,这样面试应该会多很多,就这样自己包装一下,包装不好可以找我,我有几个大厂最近做过的实习项目也可以包装一下
点赞 评论 收藏
分享
后来123321:别着急,我学院本大二,投了1100份,两个面试,其中一个还是我去线下招聘会投的简历,有时候这东西也得看运气
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务