hdu-3652 B-number 数位DP
http://acm.hdu.edu.cn/showproblem.php?pid=3652
求解所有含有13且被13整除的数。
思路:除了数位DP基本的两维,还需要维护数字头部情况,此外遇到整除问题,我们还需要维护余数。
#include <iostream> #include <cstring> #include <string> #include <queue> #include <vector> #include <map> #include <set> #include <stack> #include <cmath> #include <cstdio> #include <algorithm> #define LL long long using namespace std; const LL N = 1000000010; const LL INF = 100000009; LL dp[10][10][13][2];//bit,num,mod,type(0:no 13,1:13) LL bit[10]; void init() { bit[0] = 1; for (LL i = 1; i < 10; i++)bit[i] = bit[i - 1] * 10,bit[i]%=13; memset(dp, 0, sizeof dp); LL temp = 0; for (LL i = 0; i < 10; i++) dp[0][i][i][0] = 1; for (LL len = 1; len < 10; len++) { temp = 0; for (LL i = 0; i < 10; i++) { for (LL m = 0; m < 13; m++) { for (LL pi = 0; pi < 10; pi++) { LL temp=bit[len] * i; LL km = (temp + m) % 13; if (i == 1&&pi==3) { dp[len][i][km][1] += dp[len - 1][pi][m][0]; dp[len][i][km][1] += dp[len - 1][pi][m][1]; } else { dp[len][i][km][0] += dp[len - 1][pi][m][0]; dp[len][i][km][1] += dp[len - 1][pi][m][1]; } } } } } } LL arr[100]; LL dfs(LL pos, LL pre,LL mod,LL add) { //if (pos == -1)return add*(mod==0); if (pos == -1)return 0; LL num = arr[pos]; LL cnt = 0; for (LL i = 0; i < num; i++) { cnt += dp[pos][i][(13-mod)%13][1]; if (add||(pre==1&&i==3)) cnt += dp[pos][i][(13 - mod) % 13][0]; } if (pre == 1 && num == 3) add = 1; return cnt + dfs(pos - 1, num,(mod+bit[pos]*num)%13,add); } LL sol(LL x) { if (x == 0) return 0; LL siz = 0; while (x) arr[siz++] = x % 10, x /= 10; LL ans = 0; ans = dfs(siz - 1, -1,0,0); return ans; } int main() { cin.sync_with_stdio(false); LL n,m; init(); while (cin >> n) { cout << sol(n+1) << endl; } return 0; }