被3整除的子序列(简单DP)
链接:https://ac.nowcoder.com/acm/problem/21302
来源:牛客网
题目描述
给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模
答案对1e9+7取模
输入描述:
输入一个字符串,由数字构成,长度小于等于50
输出描述:
输出一个整数
具体思路:
dp[i][j]表示到前i个字符能凑出余数为j的个数
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 # define inf 0x3f3f3f3f 5 const int maxn = 2e5+100; 6 const int mod =1e9+7; 7 char str[maxn]; 8 ll dp[maxn][10]; 9 int main() 10 { 11 scanf("%s",str+1); 12 int len=strlen(str+1); 13 int tmp=0; 14 for(int i=1; i<=len; i++) 15 { 16 dp[i][(str[i]-'0')%3]=1; 17 for(int j=0; j<3; j++) 18 { 19 dp[i][j]+=dp[i-1][j]; 20 dp[i][j]%=mod; 21 dp[i][j]+=dp[i-1][(j+15-(str[i]-'0'))%3];// 注意这里应该是互补的 22 dp[i][j]%=mod; 23 } 24 // cout<<i<<endl; 25 // for(int j=0;j<3;j++){ 26 // cout<<j<<" "<<dp[i][j]<<endl; 27 // } 28 } 29 // cout<<i<<endl; 30 // for(int j=0;j<3;j++){ 31 // cout<<j<<" "<<dp[i][j]<<endl; 32 // } 33 printf("%lld\n",dp[len][0]); 34 return 0; 35 }