您的位置:首页 > 其它

[HDU2089] 不要62 (数位DP)

2017-06-22 19:02 369 查看

传送门

 

数位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;
}

  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: