牛客网--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]);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值