被3整除的子序列

 

题目描述

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

输入描述:

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

输出描述:

输出一个整数
示例1

输入

132

输出

3
示例2

输入

9

输出

1
示例3

输入

333

输出

7
示例4

输入

123456

输出

23
示例5

输入

00

输出

3

思路:

把字符串每个数字取模3 处理成 只有0 1 2三个字符的串。

二维数组dp[i] [j] 表示 前 i 个长度的所有子序列数位数字和取模 3 为 j 的数目( 0 <= j <= 2)

有状态转移方程 :dp[i] [j] = (dp[i - 1] [j] + dp[i - 1] [ (3 + j - m) % 3]) % 1000000007;

表示dp[i] [j]可以由两种情况递推过来:

1.  第 i 个数字不用, 直接继承 dp[i - 1] [j]。

2. 第 i 个数字与前边的一些数位和为 ( 3 +  j - m) % 3 的所有子序列相接。

最后这个数字自己构成长度为 1 的子序列单独加上。

 

代码:

 1 #include <cstdio>
 2 #include <fstream>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <deque>
 6 #include <vector>
 7 #include <queue>
 8 #include <string>
 9 #include <cstring>
10 #include <map>
11 #include <stack>
12 #include <set>
13 #include <sstream>
14 #include <iostream>
15 #define mod 1000000007
16 #define eps 1e-6
17 #define ll long long
18 #define INF 0x3f3f3f3f
19 using namespace std;
20 
21 string str;
22 int dp[55][55];
23 int main()
24 {
25     cin>>str;
26     dp[1][(str[0]-'0')%3]=1;
27     int s=str.length();
28     for(int i=2;i<=s;i++)
29     {
30         int x=(str[i-1]-'0')%3;
31         for(int j=0;j<=2;j++)
32         {
33             dp[i][j]=(dp[i-1][j]+dp[i-1][(3+j-x)%3])%mod;
34         }
35         dp[i][x]=(dp[i][x]+1)%mod;
36     }
37     printf("%d\n",dp[s][0]%mod);
38 }

 

转载于:https://www.cnblogs.com/mzchuan/p/11388153.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值