[HDU2089] 不要62 (数位DP)
数位DP入门题。
然而没有个讲解蒟蒻我真心看不懂。
推荐好的讲解一份——点我
代码(递推)
#include <cstdio>
#include <cstring>
int n, m, f[10][10], digit[10];
inline void init()
{
int i, j, k;
f[0][0] = 1;
for (i = 1; i <= 7; i++)
for (j = 0; j <= 9; j++)
for (k = 0; k <= 9; k++)
if (j != 4 && !(j == 6 && k == 2))
f[i][j] += f[i - 1][k];
}
inline int calc(int x)
{
int i, j, ans = 0;
memset(digit, 0, sizeof(digit));
for (digit[0] = 0; x; x /= 10) digit[++digit[0]] = x % 10;
for (i = digit[0]; i; i--) {
for (j = 0; j < digit[i]; j++)
if (j != 4 && !(j == 2 && digit[i + 1] == 6)) ans += f[i][j];
if (digit[i] == 4 || (digit[i] == 2 && digit[i + 1] == 6)) break;
}
return ans;
}
int main()
{
init();
while (scanf("%d %d", &n, &m), (n || m)) printf("%d\n", calc(m + 1) - calc(n));
return 0;
}
代码(记忆化搜索)
#include <cstdio>
#include <cstring>
#include <iostream>
int f[10][3], digit[10];
inline int dfs(int pos, bool sta, bool limit)
{
if (!pos) return 1;
if (!limit && f[pos][sta] ^ -1) return f[pos][sta];
int i, tmp = 0, up = limit ? digit[pos] : 9;
for (i = 0; i <= up; i++)
{
if ((sta && i == 2) || i == 4) continue;
tmp += dfs(pos - 1, i == 6, limit && i == digit[pos]);
}
if (!limit) f[pos][sta] = tmp;
return tmp;
}
inline int solve(int x)
{
for (digit[0] = 0; x; x /= 10) digit[++digit[0]] = x % 10;
return dfs(digit[0], 0, 1);
}
int main()
{
int x, y;
memset(f, -1, sizeof(f));
while (~scanf("%d %d", &x, &y) && x + y) printf("%d\n", solve(y) - solve(x - 1));
return 0;
}

浙公网安备 33010602011771号