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同类分布的主要内容,如果未能解决你的问题,请参考以下文章