zoukankan      html  css  js  c++  java
  • 被3整除的子序列/子串 (dp)

    被3整除的子序列

    题目: 给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
    答案对1e9+7取模

    题解:

    • 将所有字符转成数字在对3取模,那么序列中只有0,1,2三个数字
    • 如果是子序列,那么 (dp[i][0]) 表示(1到i) 中子序列和模3等于0的个数,(dp[i][1])(dp[i][2]) 理。
    • 如果是字串, (dp[i][0]) 表示以 i处结尾的字串和模3等于0的个数。最后答案为 (sum_{i=1}^{n}dp[i][0]​)
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MA=1e5+5;
    const int P=1e9+7;
    
    char str[100];
    int a[MA],dp[MA][3];
    
    int main()
    {
        scanf("%s",str+1);
        int n=strlen(str+1);
        for(int i=1;i<=n;++i) {
            a[i]=(str[i]-'0')%3;
            if(a[i]==0) {
                dp[i][0]=(dp[i-1][0]+dp[i-1][0]%P+1)%P;
                dp[i][1]=(dp[i-1][1]+dp[i-1][1])%P;
                dp[i][2]=(dp[i-1][2]+dp[i-1][2])%P;
            }
            else if(a[i]==1) {
                dp[i][0]=(dp[i-1][0]+dp[i-1][2])%P;
                dp[i][1]=(dp[i-1][1]+dp[i-1][0]+1)%P;
                dp[i][2]=(dp[i-1][2]+dp[i-1][1])%P;
            }
            else if(a[i]==2){
                dp[i][0]=(dp[i-1][0]+dp[i-1][1])%P;
                dp[i][1]=(dp[i-1][1]+dp[i-1][2])%P;
                dp[i][2]=(dp[i-1][2]+dp[i-1][0]+1)%P;
            }
        }
        printf("%d
    ",dp[n][0]%P);
        return 0;
    }
    
    
  • 相关阅读:
    c读取文本文档
    java类中定义接口
    android selector
    android listview
    android继承Dialog实现自定义对话框
    移植net-snmp到开发板(mini210)
    [BZOJ1901]Zju2112 Dynamic Rankings
    [BZOJ3524][Poi2014]Couriers
    [codeforces722D]Generating Sets
    [codeforces722C]Destroying Array
  • 原文地址:https://www.cnblogs.com/A-sc/p/12275828.html
Copyright © 2011-2022 走看看