[CodeForces 55D] Beautiful numbers && 数位DP

来源:互联网 发布:手机淘宝女款鞋子 编辑:程序博客网 时间:2024/05/07 17:40

凡是大于3维的状态我都莫名的想用记忆化省去一维 写法一样

注意要离散化LCM值 不然数组开不下 而且CF还报一个奇怪的错 看了我好久

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>using namespace std;typedef long long LL;const int MAXL = 2520;const int MAXN = 30;LL d[MAXN+10][MAXL+10][60];int bit[MAXN+10], Num[MAXL+10], Goback[MAXL+10], cnt;int gcd(int x, int y){while(y){int r = x % y;x = y;y = r;}return x;}LL dp(int h, int sum, int lcm, bool limit){if(h == 0) return (sum % Num[lcm]) ? 0 : 1;if(d[h][sum][lcm] != -1 && !limit) return d[h][sum][lcm];lcm = Num[lcm];LL ans = 0;int ed = limit ? bit[h] : 9;for(int i = 0; i <= ed; i++){int Newlcm;if(i == 0) Newlcm = lcm;else Newlcm = lcm / gcd(lcm, i) * i;ans += dp(h-1, (sum * 10 + i) % MAXL, Goback[Newlcm], limit && i == ed);}if(!limit) d[h][sum][Goback[lcm]] = ans;return ans;}LL solve(LL X){int Len = 0;memset(bit, 0, sizeof(bit));while(X) {bit[++Len] = X % 10;X /= 10;}return dp(Len, 0, 1, 1);}void init(){cnt = 0;memset(d, -1, sizeof(d));for(int i = 1; i <= MAXL; i++)if(!(MAXL % i))Num[++cnt] = i, Goback[i] = cnt;}int main(){init();int T; scanf("%d", &T); while(T--) {LL L, R;cin >> L >> R;LL ans = solve(R) - solve(L-1);cout << ans << '\n';}}


0 0
原创粉丝点击