[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;
}

  

posted @ 2017-06-22 19:02  zht467  阅读(100)  评论(0编辑  收藏  举报