数位dp初学

洛谷P4127 [AHOI2009]同类分布

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll dp[20][163][163];//表示余数和为md,考虑到dep位第dep位还未选,数位和为sum,余数为mod满足条件的方案数; 
 5 int a[20],md;
 6 ll L,R;
 7 ll dfs(int eq,int dep,int sum,int mod)
 8 {
 9     if(sum>md)return 0;
10     if(!dep)return (sum==md)&&(!mod);
11     if(!eq&&~dp[dep][sum][mod])return dp[dep][sum][mod];
12     int mx=eq?a[dep]:9;
13     ll ret=0;
14     for(int i=0;i<=mx;i++)
15     {
16         ret+=dfs(eq&&(mx==i),dep-1,sum+i,(mod*10+i)%md);
17     }
18     if(!eq) dp[dep][sum][mod]=ret;
19     return ret;
20 }
21 ll work(ll n)
22 {
23      
24     int cnt=0;
25     ll ret=0;
26     for(;n;n/=10)a[++cnt]=n%10;
27     for(int i=1;i<=cnt*9;i++)
28     {
29         md=i;
30         memset(dp,-1,sizeof(dp));
31         ret+=dfs(1,cnt,0,0);
32     }
33     return ret;
34 }
35 int main()
36 {
37     scanf("%lld%lld",&L,&R);
38     ll ret=work(R)-work(L-1);
39     printf("%lld",ret);
40     return 0;
41 }

 

posted @ 2021-12-11 14:03  matt-11  阅读(36)  评论(0)    收藏  举报