【数位dp】bzoj1799: [Ahoi2009]self 同类分布

各种奇怪姿势的数位dp

Description

给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。

Sample Input

10 19

Sample Output

3

HINT

【约束条件】1 ≤ a ≤ b ≤ 10^18


题目分析

好像10^18左右的数位dp都是乱搞就好了

既然是要求整除原数,那么数位之和肯定要放进状态里,并且枚举数位总和地去dp。

看上去好像$f[i][j]$表示后面$i$位总和为$j$的合法方案数不就好了吗?

考虑这种状态的转移会发现,从后面做上来不可行啊,没办法处理在开头加上一个数后,能整除数位之和的方案。并且我们启发性地发现,为了转移的合法性,需要在状态里加上余数来限制状态(因为当前不能整除的或许后面能够整除了;反之亦有可能)。

于是想到用$f[i][j][k][done(0/1)]$表示前$i$位和为$j$,除数位总和$sum$的余数为$k$,是否达到上限(done=1表示达到)的合法状态数。

最终答案显然是$\sum{f[digits][sum][0][0]+f[digits][sum][0][1]}$。当然这个sum是要枚举过去的。

如此,转移也就不难处理了,并且时间复杂度也是正确的(位数最大就18)

 

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 
 4 ll a,b;
 5 ll f[23][203][203][2];
 6 int digit[23];
 7 
 8 ll read()
 9 {
10     char ch = getchar();
11     ll num = 0;
12     bool fl = 0;
13     for (; !isdigit(ch); ch = getchar())
14         if (ch=='-') fl = 1;
15     for (; isdigit(ch); ch = getchar())
16         num = (num<<1)+(num<<3)+ch-48;
17     if (fl) num = -num;
18     return num;
19 }
20 ll solve(ll x)
21 {
22     for (digit[0]=0; x; x/=10)
23         digit[++digit[0]] = x%10;
24     for (int i=1; i<=digit[0]/2; i++)
25         std::swap(digit[i], digit[digit[0]-i+1]);
26     int mx = digit[0]*9;
27     ll ret = 0;
28     for (int sum=1; sum<=mx; sum++)
29     {
30         memset(f, 0, sizeof f);
31         f[0][0][0][1] = 1;
32         for (int i=0; i<digit[0]; i++)
33             for (int j=0; j<=i*9; j++)
34                 for (int k=0; k<sum; k++)
35                     for (int p=0; p<=1; p++)
36                         if (f[i][j][k][p])
37                             for (int t=0; t<=9; t++){
38                                 if (p&&digit[i+1] < t) break;
39                                 f[i+1][j+t][(10*k+t)%sum][p&&digit[i+1]==t] += f[i][j][k][p];
40                             }
41         ret += f[digit[0]][sum][0][0]+f[digit[0]][sum][0][1];
42     }
43     return ret;
44 }
45 int main()
46 {
47     a = read(), b = read();
48     printf("%lld\n",solve(b)-solve(a-1));
49     return 0;
50 }

 

 

 

 

END

posted @ 2018-07-23 11:15  AntiQuality  阅读(170)  评论(0编辑  收藏  举报