游游的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;
}
posted @ 2024-01-25 20:10  lipu123  阅读(74)  评论(0)    收藏  举报