交错和(数位dp)

交错和

数位DP

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 const int mod = 1e9 + 7;
 5 
 6 struct Node{
 7     LL sum, cnt;
 8 }dp[21][10][2][410];
 9 int bit[21];
10 LL base[21];
11 Node dfs(int pos, int cur, int lead, int lim, int sum){
12     Node temp;
13     temp.sum = 0; temp.cnt = 0;
14     if(pos < 0) return temp;
15     if(!lim && dp[pos][cur][lead][sum + 200].cnt != -1) return dp[pos][cur][lead][sum + 200];
16     if(pos == 0){
17         if(sum == cur) {
18             temp.sum = sum;
19             temp.cnt = 1;
20         }
21         return temp;
22     }
23     int up = lim ? bit[pos - 1] : 9;
24     Node t;
25     for(int i = 0; i <= up; i++){
26         if(lead) t = dfs(pos - 1, i, i == 0, lim && (i == up), sum);
27         else t = dfs(pos - 1, i, 0, lim && (i == up), cur - sum);
28         temp.cnt += t.cnt;
29         temp.sum = (temp.sum + t.sum + (t.cnt * cur % mod * base[pos]) % mod) % mod;
30     }
31     if(!lim) dp[pos][cur][lead][sum + 200] = temp;
32     return temp;
33 
34 }
35 int k;
36 LL solve(LL x){
37     int pos = 0;
38     while(x){
39         bit[pos++] = x % 10;
40         x /= 10;
41     }
42     Node temp = dfs(pos, 0, 1, 1, k);
43     return temp.sum;
44 }
45 
46 int main(){
47     LL a, b;
48     base[0] = 1;
49     for(int i = 0; i < 21; i++){
50         for(int j = 0; j < 10; j++){
51             for(int k = 0; k < 2; k++){
52                 for(int p = 0; p < 410; p++) {
53                     dp[i][j][k][p].sum = 0;
54                     dp[i][j][k][p].cnt = -1;
55                 }
56             }
57         }
58     }
59     for(int i = 1; i < 21; i++) base[i] = base[i - 1] * 10 % mod;
60     while(scanf("%lld %lld %d", &a, &b, &k) != EOF){
61         printf("%lld
", (solve(b) - solve(a - 1) + mod) % mod);
62     }
63 }
View Code
原文地址:https://www.cnblogs.com/yijiull/p/8502729.html