被3整除的子序列

题目描述

给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模

输入描述

输入一个字符串,由数字构成,长度小于等于50

输出描述

输出一个整数

代码实现

#include<iostream>
#include<string>

using namespace std;

//这里利用了两个性质
//1.添加下一个字符后,其实在之前的子串的尾部加上,还有其本身就可以了
//2.如果之前%3 为 2,那么下一个找mod3等于1的,加起来就是mod3 == 0的了
const int MOD = 1e9 + 7;

int main()
{
    string s;
    cin >> s;
    long long dp[50][3];  //记录数据
    dp[0][0] = 0;
    dp[0][1] = 0;
    dp[0][2] = 0;
    dp[0][(s[0] - '0') % 3]++;
    const int N = s.size();
    for (int i = 1; i < N; ++i)
    {
        int value = (s[i] - '0') % 3;
        switch (value)
        {
            //1 + 原来子串 + 原来子串和s[i]
        case 0:
            dp[i][0] = (dp[i - 1][0] * 2 + 1) % MOD;
            dp[i][1] = (dp[i - 1][1] * 2) % MOD;
            dp[i][2] = (dp[i - 1][2] * 2) % MOD;
            break;
        case 1:
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][2]) % MOD;
            dp[i][1] = (dp[i - 1][1] + dp[i - 1][0] + 1) % MOD;
            dp[i][2] = (dp[i - 1][2] + dp[i - 1][1]) % MOD;
            break;
        case 2:
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % MOD;
            dp[i][1] = (dp[i - 1][1] + dp[i - 1][2]) % MOD;
            dp[i][2] = (dp[i - 1][2] + dp[i - 1][0] + 1) % MOD;
        default:
            break;
        }
    }
    cout << dp[N - 1][0] << endl;

    return 0;

}

 

posted @ 2024-04-09 22:02  Kellen_Gram  阅读(24)  评论(0)    收藏  举报