标签:个数 read clu splay set har etc 枚举 property
UVA11361 Investigating Div-Sum Property
给定 \(A,B,K\),求在 \([A , B]\) 中,有多少个整数本身能被 \(K\) 整除,并且各个位上数字之和也能被 \(K\) 整除。
一道非常经典的数位 DP 题。
设 \(f(d,m_1,m_2)\) 表示共有 \(d\) 位待填,且这 \(d\) 位的各位数字之和模 \(K\) 余 \(m_1\),所组成的数字模 \(K\) 余 \(m_2\)。
显然:
然后稍微总结一下数位 DP 的套路:
int dfs(状态){
if(最后一位){return ...;}
if(已经搜过) return f[状态];
对这一位的单独处理 / 特殊限制。
for(下一位)
now += dfs(下一个状态);
return f[状态] = now;
}
int work(int x){
或许有的特判 + 预处理
for(枚举第一个状态)
ans += dfs(记忆化搜索);
return ans;
}
int main(){
ans = work(b) - work(a - 1);
}
主要难点事状态的设计。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 20;
const int M = 200;
int T, a, b, k, num[N];
LL p[N], f[N][M][M];
int read(){
int x = 0, f = 1; char c = getchar();
while(c < ‘0‘ || c > ‘9‘) f = (c == ‘-‘) ? -1 : 1, c = getchar();
while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - 48, c = getchar();
return x * f;
}
LL dfs(int d, int m1, int m2){
if(!d) return (!m1 && !m2);
if(f[d][m1][m2] != -1) return f[d][m1][m2];
LL now = 0;
for(int i = 0; i <= 9; i ++)
now += dfs(d - 1, ((m1 - i) % k + k) % k, ((1LL * m2 - 1LL * i * p[d - 1]) % k + k) % k);
return f[d][m1][m2] = now;
}
LL work(LL x){
if(!x) return 1LL;
// 根据后面的处理方式,防止漏掉 x 这个数没有判断。
x ++;
int cnt = 0;
for(int i = x; i; i /= 10) num[++ cnt] = i % 10;
if(cnt * 9 < k) return 1LL;
LL ans = 0;
int tot1 = 0, tot2 = 0;
for(int i = cnt; i >= 1; i --){
// 枚举前 i 位的数字填什么。
for(int j = 0; j < num[i]; j ++){
if(j){
tot1 = (tot1 + 1) % k;
tot2 = (tot2 + p[i - 1]) % k;
}
ans += dfs(i - 1, ((k - tot1) % k + k) % k, ((k - tot2) % k + k) % k);
}
// 第 i 位最后确定为 num[i],所以之前 0 ~ i-1 时后面几位没有限制。
if(num[i]){
tot1 = (tot1 + 1) % k;
tot2 = (tot2 + p[i - 1]) % k;
}
}
return ans;
}
int main(){
T = read();
p[0] = 1;
for(int i = 1; i <= 15; i ++) p[i] = p[i - 1] * 10;
while(T --){
memset(f, -1, sizeof(f));
a = read(), b = read(), k = read();
printf("%lld\n", work(b) - work(a - 1));
}
return 0;
}
UVA11361 Investigating Div-Sum Property
标签:个数 read clu splay set har etc 枚举 property
原文地址:https://www.cnblogs.com/lpf-666/p/14698744.html