数位dp大致有两种写法,第一种是通过递推关系,推出不同状态之间的数学关系,预处理出dp数组内的数据。但这对数学的要求很高,一般人很难驾驭。
第二种是通过记忆化搜索,程序直白易理解,适合大多数情况下使用。
数位dp也是有模板的,因为核心思想都是差不多的。
#include <cstdio>
#include <cstring>
int dp[8][2]; //dp数组存储什么信息视题目具体要求而定
int dfs (int * num, int pos, int status, bool limit) { //status的含义也是需要取决于题意
if (pos == 0) {
return 1;
}
if (!limit && dp[pos][status] != -1) {
return dp[pos][status];
}
int END = limit ? num[pos] : 9;
int ans = 0;
for (int i = 0; i <= END; i++) {
// if (i == 4 || (status == 1 && i == 2)) { 这一块是解决题目的核心代码
// continue;
// }
// int tmp = status;
// if (i == 6) {
// tmp = 1;
// }
// else {
// tmp = 0;
// }
// ans += dfs (num, pos - 1, tmp, limit && i == END);
}
if (!limit) {
dp[pos][status] = ans;
}
return ans;
}
int solve (int x) {
int num[8];
int cnt = 0;
while (x) {
num[++cnt] = x % 10;
x /= 10;
}
return dfs (num, cnt, 0, 1);
}
int main () {
int n, m;
memset (dp, -1, sizeof (dp));
while (~scanf ("%d%d", &n, &m) && m) {
printf ("%d\n", solve (m) - solve (n - 1));
}
return 0;
}
http://blog.csdn.net/wust_zzwh/article/details/52100392