DP-被3整除
描述
给定一个位数不大于50的数字,判断有多少子序列能够被3整除?答案可能比较大,需要对1e9+7取模
输入描述
一个数(位数不超过50)
输出描述
能够被3整除的子序列个数
思路
-
用dp[50][3] 第一维是到第i位,第二维是
mod 3的余数 -
当现在的数mod3是0:
- 0+任何数都=那个数,所以dp[i][0],[1],[2]都*2
-
当现在的数mod3是1:
- [0]+=[1]+[2],[1]+=[0]+[1],[2]+=[1]+[2]
-
当现在的数mod3是2:
- [0]+=[0]+[1],[1]+=[1]+[2],[2]+=[2]+[0]
代码
#include <bits/stdc++.h>
using namespace std;
string s;
const int mod=1e9+7;
int dp[1000001][3];
int main(){
cin>>s;
dp[0][s[0]%3]=1;
for(int i=1;i<s.size();i++){
dp[i][(s[i]-'0')%3]=1;
if((s[i]-'0')%3==0){
dp[i][0]+=dp[i-1][0]*2%mod;
dp[i][1]+=dp[i-1][1]*2%mod;
dp[i][2]+=dp[i-1][2]*2%mod;
}
if((s[i]-'0')%3==1){
dp[i][0]+=dp[i-1][0]+dp[i-1][2]%mod;
dp[i][1]+=dp[i-1][0]+dp[i-1][1]%mod;
dp[i][2]+=dp[i-1][1]+dp[i-1][2]%mod;
}
if((s[i]-'0')%3==2){
dp[i][0]+=dp[i-1][0]+dp[i-1][1]%mod;
dp[i][1]+=dp[i-1][1]+dp[i-1][2]%mod;
dp[i][2]+=dp[i-1][2]+dp[i-1][0]%mod;
}
}
cout<<dp[s.size()-1][0];
return 0;
}
浙公网安备 33010602011771号