hdu3652 B-number 数位dp
Posted wstong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3652 B-number 数位dp相关的知识,希望对你有一定的参考价值。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 15; 4 int dp[maxn][maxn][maxn][maxn]; 5 // dp[i][j][state][r] i表示位数,j表示开头,state是0或1表示是否已经出现了"13"这个子串 6 int base[maxn]; 7 void init() { 8 base[0] = 1; 9 for (int i = 1; i <= 10; i++) { 10 base[i] = base[i-1]*10; 11 } 12 for (int i = 0; i <= 9; i++) { 13 dp[1][i][0][i] = 1; 14 } 15 for (int i = 2; i <= 10; i++) { 16 for (int j = 0; j <= 9; j++) { 17 for (int x = 0; x <= 9; x++) { 18 int t = base[i-1]*j % 13; 19 for (int r = 0; r <= 12; r++) { 20 dp[i][j][1][(r+t)%13] += dp[i-1][x][1][r]; 21 if (j == 1 && x == 3) { // 出现了13这个子串 22 dp[i][j][1][(r+t)%13] += dp[i-1][x][0][r]; 23 } 24 else { 25 dp[i][j][0][(r+t)%13] += dp[i-1][x][0][r]; 26 } 27 } 28 } 29 } 30 } 31 } 32 int calc(int n) { 33 n++; 34 int digit[15] = {0}; 35 int lenstr = 0; 36 while (n/10 > 0) { 37 digit[++lenstr] = n%10; 38 n /= 10; 39 } 40 digit[++lenstr] = n%10; 41 int ans = 0; 42 int mod = 0; 43 bool flag = false; 44 for (int i = lenstr; i >= 1; i--) { 45 for (int j = 0; j <= digit[i]-1; j++) { 46 ans += dp[i][j][1][(13-mod)%13]; 47 if (flag || j == 3 && digit[i+1] == 1) { 48 ans += dp[i][j][0][(13-mod)%13]; 49 } 50 } 51 if (digit[i] == 3 && digit[i+1] == 1) { 52 flag = true; 53 } 54 mod = (mod+digit[i]*base[i-1])%13; 55 } 56 return ans; 57 } 58 int main() { 59 int n; 60 init(); 61 while (~scanf("%d",&n)) { 62 printf("%d ",calc(n)); 63 } 64 return 0; 65 }
以上是关于hdu3652 B-number 数位dp的主要内容,如果未能解决你的问题,请参考以下文章