HDU-3652 B-number (数位DP+模运算)

这里写图片描述

思路:

  • 如果只判断子串是否有13的话非常简单,这题还加了一个条件就是要被13整除;
  • 这里就要用到模运算的性质,即(a+b+c)%d = (a%d + b%d + c%d)%d。

Code:

 1 #include<bits/stdc++.h>
 2 #define M(a, b) memset(a, b, sizeof(a))
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 int a[15], dp[15][14][3];
 7 
 8 ll dfs(int cur, int mod, int sta, bool limit){
 9     if (cur == 0) return sta == 2 && !mod;
10     if (!limit && ~dp[cur][mod][sta]) return dp[cur][mod][sta];
11     int up = limit ? a[cur] : 9;
12     ll ans = 0;
13     for (int i = 0; i <= up; ++i){
14         int m = (mod * 10 + i) % 13;
15         if (sta == 2 || (sta == 1 && i == 3)) ans += dfs(cur-1, m, 2, limit && a[cur] == i);
16         else if (i == 1) ans += dfs(cur-1, m, 1, limit && a[cur] == i);
17         else ans += dfs(cur-1, m, 0, limit && a[cur] == i);
18     }
19     if (!limit) dp[cur][mod][sta] = ans;
20     return ans;
21 }
22 
23 ll cal(ll n){
24     int len = 0;
25     while(n){
26         a[++len] = n % 10;
27         n /= 10;
28     }
29     return dfs(len, 0, 0, 1);
30 }
31 
32 int main()
33 {
34     ll n;
35     while(~scanf("%lld", &n)){
36         M(dp, -1);
37         printf("%lld\n", cal(n));
38     }
39 
40     return 0;
41 }

 

posted @ 2017-01-20 22:44  Robin!  阅读(108)  评论(0编辑  收藏  举报