【HDU 2089】不要62
http://acm.hdu.edu.cn/showproblem.php?pid=2089
数位dp,参照了打野的博客
预处理出f数组,f[i][j]表示第i位为数字j时的可行的数字总数。
对于区间[l,r],可以用区间[1,r]-[1,l)求得。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int in() { int k = 0, fh = 1; char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) if (c == '-') fh = -1; for(; c >= '0' && c <= '9'; c = getchar()) k = (k << 3) + (k << 1) + c - '0'; return k * fh; } int f[8][10], digit[10], len; int cal(int num) { len = 0; while (num) {digit[++len] = num % 10; num /= 10;} digit[len + 1] = 0; int ret = 0; for(int i = len; i >= 1; --i) { for(int j = 0; j < digit[i]; ++j) if (j != 4 && !(digit[i + 1] == 6 && j == 2)) ret += f[i][j]; if (digit[i] == 4 || (digit[i + 1] == 6 && digit[i] == 2)) break; } return ret; } int main() { f[0][0] = 1; for(int i = 1; i <= 7; ++i) for(int j = 0; j <= 9; ++j) if (j != 4) for(int k = 0; k <= 9; ++k) if (k != 4 && !(j == 6 && k == 2)) f[i][j] += f[i - 1][k]; int n, m; n = in(); m = in(); if (n > m) swap(n, m); while (n != 0 && m != 0) { printf("%d\n", cal(m + 1) - cal(n)); n = in(); m = in(); if (n > m) swap(n, m); } return 0; }
现在才学数位dp,←noip滚粗的前兆_(:з」∠)_
NOI 2017 Bless All