【DP】被3整除的子序列

【题意】

  给定一个数字串,然后求出所有子序列中能被3整除的个数。

【题解】

  1、状态表示:f[i][j]指的是,以s[i]结尾的对3取余后值为j的集合
  2、f[i][j] 方案数
  3、集合划分:每次转移都是从f[1,2,...,i1][0,1,2]

 

 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\n",ans);
31     return 0;
32 }
View Code

 

posted @ 2020-03-31 10:29  Osea  阅读(184)  评论(0编辑  收藏  举报