动态规划、
——牛客21302
题目描述
给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
答案对1e9+7取模
输入描述:
输入一个字符串,由数字构成,长度小于等于50
输出描述:
输出一个整数
示例1
输入
132
输出
3
示例2
输入
9
输出
1
示例3
输入
333
输出
7
示例4
输入
123456
输出
23
示例5
输入
00
输出
3
备注:
n为长度
子任务1: n <= 5
子任务2: n <= 20
子任务3: 无限制
解析:
dp[i][j]+=dp[i-1][j]+dp[i-1][(j-s[i]+‘0’+9)%3];
//在第i位时,当余数是j时,可以等于当在前一位加上或者不加上这一位的值得总和
注意啦:1.这里每个初始值,就是可以当前面什么都没有,从这一未开始,即就单单这一位数的初始值
dp[0][(s[0]-‘0’)%3]=1;//很重要哦
2.就是模的时候一定要注意,中间是否也会超,所以也要加
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s;
ll dp[100][3];
int main()
{
while(cin>>s)
{
ll ans=0;
memset(dp,0,sizeof(dp));
dp[0][(s[0]-'0')%3]=1;
for(int i=1;i<s.length();i++){
dp[i][(s[i]-'0')%3]=1;
for(int j=0;j<3;j++)
{
dp[i][j]+=dp[i-1][j]+dp[i-1][(j-s[i]+'0'+9)%3]%1000000007;
dp[i][j]%=1000000007;
}
}
printf("%lld\n",dp[s.length()-1][0]);
}
}