【题意】
给定一个数字串,然后求出所有子序列中能被3整除的个数。
【题解】
1、状态表示:f[i][j]指的是,以s[i]结尾的对3取余后值为j的集合
2、f[i][j] 方案数
3、集合划分:每次转移都是从f[1,2,...,i−1][0,1,2]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 typedef long long ll ; 8 const ll mod = 1e9 + 7 ; 9 const int N = 1e3 + 10; 10 ll f[N][3] ; 11 char s[N]; 12 int main() 13 { 14 scanf("%s",s+1); 15 int n = strlen( s + 1 ); 16 17 for( int i = 1 ; i <= n ; i ++ ) 18 f[i][(s[i]-'0')%3] = 1 ; 19 for( int i = 1 ; i <= n ; i++ ){ 20 for( int j = 0 ; j < 3 ; j++ ){ 21 for( int k = i+1 ; k <= n ; k ++ ){ 22 f[k][(j+s[k]-'0')%3] = ( f[k][(j+s[k]-'0')%3] + f[i][j] ) % mod ; 23 } 24 } 25 } 26 ll ans = 0 ; 27 for( int i = 1 ; i <= n ; i++ ){ 28 ans = ( ans + f[i][0] ) % mod ; 29 } 30 printf("%lld ",ans); 31 return 0; 32 }