uva 11361 Investigating Div-Sum Property

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2346

  不知道算什么题,好像是数位dp,不过在切递推的题,所以这题应该算是递推。

  首先要预处理出dp[i][j][k][p],表示一共有i位数字,其中数字和mod p余j而且这个数mod p余k的个数。然后就是枚举每一位,分段处理出结果。

代码如下:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 typedef long long LL;
 9 const int N = 12;
10 const int M = 55;
11 LL dp[N][M][M][M], ep[N];
12 
13 void PRE() {
14     for (int i = 0; i < M; i++) dp[0][0][0][i] = 1;
15     for (int i = 0; i < N - 1; i++) {
16         for (int j = 0; j < M; j++) {
17             for (int k = 0; k < M; k++) {
18                 for (int p = 1; p < M; p++) {
19                     for (int q = 0; q < 10; q++) {
20                         dp[i + 1][(j + q) % p][(k * 10 + q) % p][p] += dp[i][j][k][p];
21                     }
22                 }
23             }
24         }
25     }
26     ep[0] = 1;
27     for (int i = 0; i < N - 1; i++) ep[i + 1] = ep[i] * 10;
28     //cout << dp[1][0][0][1] << endl;
29     //cout << dp[1][0][0][2] << endl;
30     //cout << dp[1][0][0][3] << endl;
31     //cout << dp[3][1][1][4] << endl;
32 }
33 
34 LL cal(int x, int k) {
35     int p = 0, dgs = 0;
36     if (k >= M) return 0;
37     LL ret = 0;
38     while (x >= ep[p]) p++;
39     while (p > 0) {
40         p--;
41         int cdg = x / ep[p] % 10;
42         for (int i = 0; i < cdg; i++) {
43             ret += dp[p][(k - (dgs + i) % k) % k][(k - (x / ep[p + 1] * 10 + i) * ep[p] % k) % k][k];
44         }
45         dgs += cdg;
46     }
47     return ret + dp[0][(k - dgs % k) % k][(k - x % k) % k][k];
48 }
49 
50 int main() {
51     PRE();
52     int T, n, m, k;
53     cin >> T;
54     while (T-- && cin >> n >> m >> k) cout << cal(m, k) - cal(n - 1, k) << endl;
55     return 0;
56 }
View Code

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/uva_11361_Lyon.html