AHOI 2009同类分布

Posted awhitewall

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AHOI 2009同类分布相关的知识,希望对你有一定的参考价值。

(Solution)

发现之前代码的样式时常会出现不同颜色很不协调的东东,,,然后,发现原来是代码那一栏没打 cpp。(笑)

言归正传,感觉这道数位 DP 非常神奇。我们考虑到其实各个数位之和比较小,可以直接枚举。

这样就解决了一个重要的问题:我们的“数”范围太大,状态装不下。(不过注意要保证解的各个数位之和等于模数)

直接套数位 DP 板子即可。

(Code)

#pragma GCC optimize(2)
#include <cstdio>
#include <cstring>
typedef long long ll;

int a[20];
ll dp[20][200][200], mod;

ll read() {
    ll x = 0, f = 1; char s;
    while((s = getchar()) < '0' || s > '9') if(s == '-') f = -1;
    while(s >= '0' && s <= '9') {x = (x << 1) + (x << 3) + (s ^ 48); s = getchar();}
    return x * f;
}

ll DP(const int p, const int s, const int sta, const bool lim) {
    if(p == -1) return sta == 0 && s == mod;
    if(! lim && (~ dp[p][s][sta])) return dp[p][s][sta];
    int up = lim ? a[p] : 9; ll ans = 0;
    for(int i = 0; i <= up; ++ i)
        ans += DP(p - 1, s + i, (1ll * sta * 10 + i) % mod, lim && i == up);
    return lim ? ans : dp[p][s][sta] = ans;
}

ll get(ll x) {
    int p = -1; ll ans = 0;
    while(x) {a[++ p] = x % 10; x /= 10;}
    for(mod = 1; mod <= (p + 1) * 9; ++ mod) memset(dp, -1, sizeof dp), ans += DP(p, 0, 0, 1);
    return ans;
}

int main() {
    ll a = read(), b = read();
    printf("%lld
", get(b) - get(a - 1));
    return 0;
}

以上是关于AHOI 2009同类分布的主要内容,如果未能解决你的问题,请参考以下文章

P4127 [AHOI2009]同类分布

[AHOI2009]同类分布

bzoj 1799 [Ahoi2009]self 同类分布(数位DP)

P4127 [AHOI2009]同类分布

AHOI2009同类分布 题解(数位DP)

luogu P4127 [AHOI2009]同类分布 数位dp