题意:求1到n中包含'13'('13'不一定连续)且能被13整除的数的个数。
这是我第一道比较了能看懂的数位dp。定义状态dp[pos][res][sta]表示处理到第pos位,模的余数为0,sta取0,1,2,0表示无'13',1表示有1无3,2表示有'13'。
特别注意就是16行只要i==1时,nsta就是1,不用加sta=0,否则会WA。。。。
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int dp[20][20][3]; 5 int digit[20]; 6 7 int dfs(int pos, int res, int sta, bool limit) 8 { 9 if (pos == 0) return res == 0 && sta == 2; 10 if (!limit&&dp[pos][res][sta] != -1) return dp[pos][res][sta]; 11 int ans = 0; 12 int up = limit ? digit[pos] : 9; 13 for (int i = 0; i <= up; i++) { 14 int nsta; 15 if (sta == 1 && i == 3 || sta == 2) nsta = 2; 16 else if (i == 1) nsta = 1; 17 else nsta = 0; 18 ans += dfs(pos - 1, (res * 10 + i) % 13, nsta, limit&&i == up); 19 } 20 if (!limit) dp[pos][res][sta] = ans; 21 return ans; 22 } 23 24 int solve(int x) 25 { 26 int len = 0; 27 while (x) 28 { 29 digit[++len] = x % 10; 30 x /= 10; 31 } 32 return dfs(len, 0, 0, true); 33 } 34 35 int main() 36 { 37 int n; 38 memset(dp, -1, sizeof(dp)); 39 while (cin>>n) 40 { 41 cout << solve(n) << endl; 42 } 43 return 0; 44 }