CSUSTOJ 你真的会字符串吗?(DP)

CSUSTOJ 你真的会字符串吗?(DP)_第1张图片

思路:
最后结果每一位都等于 s [ i ] s[i] s[i]
只要知道当前位的 p r e [ i ] pre[i] pre[i]值和当前位的 t [ i ] t[i] t[i]值就好了。
所以定义 d p [ i ] [ j ] dp[i][j] dp[i][j]为到了第 i i i为, p r e [ i + 1 ] = j pre[i+1]=j pre[i+1]=j的方案数。
然后直接枚举当前位和当前 p r e [ i ] pre[i] pre[i]值就可以转移了。

#pragma GCC optimize(2)
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef unsigned long long ull;
typedef long long ll;
const int maxn = 2e5 + 7;
const int mod = 998244353;

ll f[maxn][100];
int a[maxn];

int main() {
    int n;scanf("%d",&n);
    for(int i = n;i >= 1;i--) {
        scanf("%1d",&a[i]);
    }
    for(int i = 0;i <= 9;i++) {
        if(i * a[1] % 10 == a[1]) f[1][a[1] * i / 10]++;
    }
    for(int i = 2;i <= n;i++) {
        for(int j = 0;j <= 81;j++) { //pre[i]的值
            for(int k = 0;k <= 9;k++) {
                int num = j + k * a[i];
                if(num % 10 == a[i]) {
                    int pre_now = (a[i] * k + j) / 10;
                    f[i][pre_now] += f[i - 1][j];
                    f[i][pre_now] %= mod;
                }
            }
        }
    }
    
    ll ans = 0;
    for(int i = 0;i <= 81;i++) {
        ans = (ans + f[n][i]) % mod;
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(CSUSTOJ 你真的会字符串吗?(DP))