HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp

Posted qaqorz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp相关的知识,希望对你有一定的参考价值。

题意:给出区间【L,R】,求其中有多少个数满足自身被数位和整除

比赛出了刚好没刷的原题系列= =

思路:枚举的过程中很好记录数位和,但是一个数字可以很大(1e9、1e12),不能加到状态里

既然相对很小的量是数位和,考虑枚举最终的数位和作为模数,用它来模过程中得到的数字num,这样num就可以加入状态了

最后只要枚举到的数位和确实是这个模数,就是一个可行解,明确状态之后套模板即可

技术分享图片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int a[10], dp[10][90][90][90];
 7 
 8 int dfs(int pos, int sum, int mod, int res, bool lim){
 9     if (pos == -1) return (sum == 0 && res == mod);
10     if (!lim && dp[pos][sum][mod][res] != -1) return dp[pos][sum][mod][res];
11     int r = lim ? a[pos] : 9;
12     int ans = 0;
13     for (int i = 0; i <= r; i++){
14         ans += dfs(pos-1, (sum*10+i)%mod, mod, res+i, lim && i == a[pos]);
15     }
16     if (!lim) dp[pos][sum][mod][res] = ans;
17     return ans;
18 }
19 
20 int solve(int x){
21     int pos = 0;
22     while (x){
23         a[pos++] = x%10;
24         x /= 10;
25     }
26     int ans = 0;
27     for (int i = 1; i <= 81; i++)
28         ans += dfs(pos-1, 0, i, 0, 1);
29     return ans;
30 }
31 
32 int main(){
33     int t, a, b, kase = 0;
34     scanf("%d", &t);
35     memset(dp, -1, sizeof dp);
36     while (t--){
37         scanf("%d%d", &a, &b);
38         printf("Case %d: %d
", ++kase, solve(b)-solve(a-1));
39     }
40     return 0;
41 }
View Code

 

以上是关于HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 4389 X mod f(x) (数位dp)

hdu 4389 X mod f(x) 数位dp

hdu4389 Xmod f(x) 数位DP

HDU 4389 数位dp

错排公式

HDU X mod f(x) (数位DP)