游游的9的倍数(动态规划)
链接:https://ac.nowcoder.com/acm/problem/254017
来源:牛客网
问题描述:
游游拿到了一个数字串,她想取一个该数字串的子序列(子序列在原串中可以不连续),使得该子序列是9的倍数。子序列可以包含前导零。
游游想知道,一共能取多少个合法的子序列?答案请对 \(10^9+7\)取模。
我们定义,若两个子序列在原串中的位置不同,则认为它们不同。
输入描述:
一个长度不超过200000的,仅由'0'~'9' 十种字符组成的字符串。
输出描述:
子序列是9的倍数的数量。答案请对\(10^9+7\)取模。
示例1
输入
1188
输出
5
说明
共可以取4个不同的"18"子序列,和一个"1188"子序列,都是9的倍数。
示例2
输入
0123
输出
1
说明
只有子序列"0"是9的倍数。
这个题是个dp,dp[i][j]代表前i个模数为j个个数
#include<bits/stdc++.h>
using namespace std;
const int M = 1000000007;
const int N = 200005;
string s;
long long int a[N] , dp[N][10];
int main(){
cin >> s;
int len = s.length();
for(int i = 0 ; i < len ; i++){
int k = s[i] - '0';
a[i+1] = k;
dp[i+1][k%9]++;
}
int n = len;
for(int i = 1 ; i <= n ; i++){
for(int j = 0 ; j <= 8 ; j++){
dp[i][(j+a[i])%9] = (dp[i][(j+a[i])%9] + dp[i-1][j] + dp[i-1][(j+a[i])%9])%M;
}
}
cout << dp[n][0]%M << endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int Max=2e5+5;
const int mod=1e9+7;
long long dp[Max][10];
int main(){
string s;cin>>s;
int len=s.size();
s=" "+s;
dp[0][0]=1;
for(int i=1;i<=len;i++){
for(int j=0;j<9;j++) dp[i][j]=dp[i-1][j];//不选
for(int j=0;j<9;j++){
int l=(j+s[i]-'0')%9;
dp[i][l]+=dp[i-1][j];//选
dp[i][l]%=mod;
}
}
cout<<dp[len][0]-1<<endl;
}