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;
}

posted on 2024-07-11 20:02  可爱楷玩算法  阅读(33)  评论(0)    收藏  举报

导航