链接:https://ac.nowcoder.com/acm/problem/21302
来源:牛客网
题目描述
给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模
输入描述:
输入一个字符串,由数字构成,长度小于等于50
输出描述:
输出一个整数
示例1
输入
复制132
132
输出
复制3
3
示例2
输入
复制9
9
输出
复制1
1
示例3
输入
复制333
333
输出
复制7
7
示例4
输入
复制123456
123456
输出
复制23
23
示例5
输入
复制00
00
输出
复制3
3
备注:
n为长度 子任务1: n <= 5 子任务2: n <= 20 子任务3: 无限制
当第 i 个数模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];
当第 i 个数模3等于1时:dp[i][0] = dp[i-1][0]+dp[i-1][2]; dp[i-1][1] = dp[i-1][1]+dp[i-1][0]+1; dp[i][2] = dp[i-1][2]+dp[i-1][1];
当第 i 个数模3等于2时:dp[i][0] = dp[i-1][0]+dp[i-1][1]; dp[i-1][1] = dp[i-1][1]+dp[i-1][2]; dp[i][2] = dp[i-1][2]+dp[i-1][0]+1;
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int main(){
string t;
cin>>t;
int len=t.length();
int dp[55][3];
memset(dp,0,sizeof(dp));//不能省略这一步
int m=0;
dp[0][(t[0]-'0')%3]=1;
for(int i=1;i<len;i++){
m=(t[i]-'0')%3;
dp[i][m]=(dp[i][m]+1)%mod;
for(int j=0;j<3;j++){
dp[i][j]+=(dp[i-1][j]+dp[i-1][(j+3-m)%3])%mod;//这个mod不能去掉
}
//dp[i][m]=(dp[i][m]+1)%mod;
}
/*for(int q=0;q<len;q++){
for(int w=0;w<3;w++){
cout<<dp[q][w]<<" ";
}
cout<<endl;
}*/
cout<<dp[len-1][0]%mod<<endl;
return 0;
}