数位DP hihocoder1791
Posted leesongt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数位DP hihocoder1791相关的知识,希望对你有一定的参考价值。
1 /* 2 题意:求 1...n, n<10^12中满足x%sum(x)==0的数的个数,sum(x)为x的各个位数的和 3 题解:数位DP 4 时间:2018.08.03 5 */ 6 7 #include <bits/stdc++.h> 8 using namespace std; 9 10 typedef long long LL; 11 const int MAXN = 100005; 12 const LL MOD7 = 1e9+7; 13 14 LL dp[15][125][125][125]; 15 16 // 位数, 和, 模, 余数, dp[i][s][R][r]当前位数是i, 和为s,对R取模余数是r的个数 17 // 每次枚举最后一位, 有 dp[i+1][s+j][R][(r*10+j)%R] += dp[i][s][R][r]; 18 19 void init() 20 { 21 memset(dp,0LL,sizeof(dp)); 22 for (int i=1;i<=9*12;++i) dp[0][0][i][0]=1; 23 for (int i=0;i<=12;++i) 24 { 25 for (int s=0;s<=9*12;++s) 26 { 27 for (int R=1;R<=9*12;++R) 28 { 29 for (int r=0;r<R;++r) 30 { 31 if (dp[i][s][R][r]) 32 { 33 for (int j=0;j<=9;++j) 34 { 35 dp[i+1][s+j][R][(r*10+j)%R]+=dp[i][s][R][r]; 36 } 37 } 38 } 39 } 40 } 41 } 42 } 43 44 int b[15]; 45 int m; 46 LL n; 47 48 LL get_b(LL n) 49 { 50 LL t=1; 51 m=0; 52 while (n) 53 { 54 b[m++]=n%10; 55 n/=10; 56 t*=10; 57 } 58 reverse(b,b+m); 59 return t/10; 60 } 61 62 63 // 统计<n的满足条件的方案数。 64 // 每次从高位枚举n=a1a2a3...am的一位,例如a2=3 枚举j=0, 1, 2, 3, 然后统计a1固定时,第二位为j时,枚举剩下位置的和为s 65 // 对应的结果就是就是,长度为 len = m-2, s, 66 // 模数 R = 前面固定的和 + j + s 67 // 需要的余数是 r = (R-(前面固定位置的值+ j对应的值) % R) %R 68 // 也就是 dp[len][s][sum+j+s][(R-(value+j*q)%R)%R] , sum是前面固定位置的总和,value为其对应的值,q=10^len,当前位的权重。 69 70 LL solve(LL n) 71 { 72 LL q = get_b(n); 73 // for (int i=0;i<m;++i) cout<<b[i]<<" ";cout<<endl; 74 // cout<<q<<endl; 75 LL ans=0; 76 int sum=0; 77 LL value=0; 78 for (int i=0;i<m;++i) 79 { 80 int len= m-i-1; 81 for (int j=0;j<b[i];++j) 82 { 83 for (int s=0;s<=9*len;++s) 84 { 85 int R = sum+j+s; 86 if (R>0) 87 { 88 int r=(int)(R-(value+j*q)%R) % R; 89 ans+=dp[len][s][R][r]; 90 } 91 } 92 } 93 value += q*b[i]; 94 q/=10; 95 sum+=b[i]; 96 } 97 int tmp=0; 98 for (int i=0;i<m;++i) tmp+=b[i]; 99 ans+=(n%tmp==0); 100 return ans; 101 } 102 103 int main() 104 { 105 #ifndef ONLINE_JUDGE 106 // freopen("test.txt","r",stdin); 107 #endif // ONLINE_JUDGE 108 init(); 109 scanf("%lld",&n); 110 printf("%lld ",solve(n)); 111 return 0; 112 }
以上是关于数位DP hihocoder1791的主要内容,如果未能解决你的问题,请参考以下文章