牛客网--21302--被3整除的子序列

题目描述:
给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模
输入描述:
输入一个字符串,由数字构成,长度小于等于50
输出描述:
输出一个整数
输入:
132
9
3
1
题意:
题目描述
题解
因为是子序列,所以可以不连续,因此需要保存每个区间上余数为0,1,2的数目 用dp[i][k] 表示从0到i区间上,余数为k的数目.
代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;
const int maxn = 55;
const int mod = 1e9+7;
char s[maxn];
ll dp[maxn][5];

int main(){
    while(scanf("%s",s)!=EOF){
        int l = strlen(s);
        for(int i = 0; i < l; i ++){
            int t = s[i] - '0';
            t %= 3;
            dp[i][t] = 1;
        }
        for(int i = 1; i < l; i ++){
            int t = s[i] - '0';
            if(t % 3 == 0){
                dp[i][0] = 2 * dp[i - 1][0] + 1;
                dp[i][1] = 2 * dp[i - 1][1];
                dp[i][2] = 2 * dp[i - 1][2];
            }
            else if(t % 3 == 1){
                dp[i][0] = dp[i - 1][0] + dp[i - 1][2];
                dp[i][1] = dp[i - 1][1] + dp[i - 1][0] + 1;
                dp[i][2] = dp[i - 1][1] + dp[i - 1][2];
            }
            else{
                dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
                dp[i][1] = dp[i - 1][1] + dp[i - 1][2];
                dp[i][2] = dp[i - 1][2] + dp[i - 1][0] + 1;
            }
            for(int j = 0; j < 3; j ++){
                dp[i][j] %= mod;
            }
        }
        printf("%lld\n",dp[l - 1][0]);
    }
}

发布了228 篇原创文章 · 获赞 1 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/Ypopstar/article/details/105161197