HDU-4507 数位DP 记录一个毒瘤错误orz

题意:求区间【L,R】满足以下性质:(1)数位中没有7,(2)数位和不被7整除,(3)数字本身不被7整除  的所有数字的平方和

 

先记录一个毒瘤错误。。。感觉自己好不会设状态啊。数位dp的状态自己都不知道是不是对的能不能转移QAQ。

错误代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 using namespace std;
 6 
 7 int a[20];
 8 LL dp[20][200][10];
 9 const int mod = 1e9+7;
10 
11 LL dfs(int pos, int sum, LL n, bool lim){
12     if (pos == -1) {
13         if (sum % 7 == 0) return 0;
14         if (n % 7 == 0) return 0;
15         return (n%mod)*(n%mod)%mod;
16     }
17     if (!lim && dp[pos][sum][n%7] != -1) return dp[pos][sum][n%7];
18     LL ans = 0;
19     int r = lim ? a[pos] : 9;
20     for (int i = 0; i <= r; i++){
21         if (i == 7) continue;
22         ans = (ans + dfs(pos-1, sum+i, n*10+i, lim && i == a[pos]) + mod) % mod;
23     }
24     if (!lim) dp[pos][sum][n%7] = ans;
25     return ans;
26 }
27 
28 LL solve(LL x){
29     int pos = 0;
30     while (x){
31         a[pos++] = x%10;
32         x /= 10;
33     }
34     return dfs(pos-1, 0, 0, 1);
35 }
36 
37 int main(){
38     int t;
39     LL a, b;
40     scanf("%d", &t);
41     memset(dp, -1, sizeof dp);
42     while (t--){
43         scanf("%lld%lld", &a, &b);
44         printf("%lld\n", (solve(b)-solve(a-1)+mod)%mod);
45     }
46     return 0;
47 }
View Code

 

AC代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 using namespace std;
 6 
 7 int a[20];
 8 LL p[30];
 9 const int mod = 1e9+7;
10 
11 struct sta{
12     LL cnt, ans, sum;
13     sta(LL cnt = 0, LL ans = 0, LL sum = 0): cnt(cnt), ans(ans), sum(sum){}
14 }dp[20][10][10];
15 
16 sta dfs(int pos, int sum, int n, bool lim){
17     if (pos == -1) return sum != 0 && n != 0 ? sta(1, 0, 0) : sta(0, 0, 0);
18     if (!lim && dp[pos][sum][n].cnt != -1) return dp[pos][sum][n];
19     sta ans(0, 0, 0);
20     int r = lim ? a[pos] : 9;
21     for (int i = 0; i <= r; i++){
22         if (i == 7) continue;
23         sta nxt = dfs(pos-1, (sum+i)%7, (n*10+i)%7, lim && i == a[pos]);
24         ans.cnt = (ans.cnt + nxt.cnt) % mod;
25         ans.sum = (ans.sum + (nxt.sum + ((p[pos+1] * i) % mod) * nxt.cnt % mod) % mod) % mod;
26         ans.ans = (ans.ans + (nxt.ans + ((2*p[pos+1]*i) % mod) * nxt.sum) % mod) % mod;
27         ans.ans = (ans.ans + ((nxt.cnt * p[pos+1]) % mod * p[pos+1] % mod * i * i % mod)) % mod;
28     }
29     if (!lim) dp[pos][sum][n] = ans;
30     return ans;
31 }
32 
33 LL solve(LL x){
34     int pos = 0;
35     while (x){
36         a[pos++] = x%10;
37         x /= 10;
38     }
39     return dfs(pos-1, 0, 0, 1).ans;
40 }
41 
42 int main(){
43     int t;
44     LL l, r;
45     scanf("%d", &t);
46     p[1] = 1;
47     for (int i = 2; i <= 20; i++) p[i] = (p[i-1]*10)%mod;
48     memset(dp, -1, sizeof dp);
49     while (t--){
50         scanf("%lld%lld", &l, &r);
51         printf("%lld\n", (solve(r)-solve(l-1)+mod)%mod);
52     }
53     return 0;
54 }

 

 

posted @ 2018-07-25 01:11  QAQorz  阅读(214)  评论(0编辑  收藏  举报