被3整除的子序列

解题思路:1.首先要明白子序列的意思:如qwwweec,(qwe,wec等都是它的子序列);
2.一个数如果可以被3整除,那么各位数之和也可以被3整除。
3.dp[i][j]表示前i位数子序列的余数为j的个数;(m表示余数,dp[i][j]应该等于dp[i-1][j]+dp[i-1][(j+3-m)%3]的和再模mod);
令后半部分为dp[i-1][x],所以(x+m)%3=j+3,即x=(j+3-m)%3。

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

#include<cstring>

using namespace std;
typedef long long ll;
const int mod = 1e9+7;

int (){
string ss;
cin>>ss;
int len = ss.length();
int dp[55][3];
memset(dp,0,sizeof(dp));
dp[0][(ss[0]-'0')%3]=1;
for(int i=1;i<len;i++){
int m=(ss[i]-'0')%3;

for(int j=0;j<3;j++){
dp[i][j]=(dp[i-1][j]+dp[i-1][(j+3-m)%3])%mod;//dp公式
}
dp[i][m]=(dp[i][m]+1)%mod;//初始化时为0,故计算时需加1
}
cout<<dp[len-1][0]%mod<<endl;

return 0;
}