数位DP求调

CF55D Beautiful numbers

超时了。。。。
by 小超手123 @ 2023-06-08 14:58:28


@[小超手123](/user/490978) 不用 reverse,倒着 DP,然后不要每次 memset
by 5k_sync_closer @ 2023-06-08 15:56:23


@[小超手123](/user/490978) 这样做的话 limit 就不能开在状态里,要记搜的时候特判,因为每次上限不一样
by 5k_sync_closer @ 2023-06-08 15:57:14


@[5k_sync_closer](/user/388651) 为什么不要每次 memset
by 小超手123 @ 2023-06-08 16:04:05


@[5k_sync_closer](/user/388651) 改成这样了,但是WA了 ```cpp #include<bits/stdc++.h> using namespace std; int T; int P[2530], Q[50], tot; long long f[20][2522][49]; //f[i][j][k][l] 表示前 i 位,当前数 % 2520 = j , 最大公倍数 = k , l:卡没卡住 int A[20], num; int gcd(int x, int y) { if(y == 0) return x; return gcd(y, x % y); } int lcm(int x, int y) { return x * y / gcd(x, y); } long long dfs(int Pos, int now, int S, int lim) { if(Pos == 0) { if(now % Q[S] == 0) return 1; else return 0; } if(f[Pos][now][S] != -1 && lim == 0) return f[Pos][now][S]; long long ans = 0; for(int i = 0; i <= (lim == 1 ? A[Pos] : 9); i++) ans += dfs(Pos - 1, (now * 10 + i) % 2520, P[i == 0 ? Q[S] : lcm(Q[S], i)], (i == A[Pos]) && lim); if(lim == 0)f[Pos][now][S] = ans; return ans; } long long Sol(long long x) { num = 0; while(x) { A[++num] = x % 10; x /= 10; } return dfs(num, 0, 0, 1); } signed main() { Q[0] = 1; for(int i = 1; i <= 2520; i++) if(2520 % i == 0) P[i] = ++tot, Q[tot] = i; // cout << tot << endl; cin >> T; while(T--) { long long l, r; cin >> l >> r; cout << Sol(r) - Sol(l - 1) << endl; } return 0; } ```
by 小超手123 @ 2023-06-08 16:15:48


@[小超手123](/user/490978) 你至少在 main 最开始 memset 一次吧……
by 5k_sync_closer @ 2023-06-08 16:23:01


@[5k_sync_closer](/user/388651) 谢了
by 小超手123 @ 2023-06-08 16:30:27


|