一名苦逼的OIer,想成为ACMer

Iowa_Battleship

HDOJ2089 不要62

原题链接

数位\(DP\)入门题。
记录前一个枚举到的数位,在每次枚举的时候避开\(4\),如果前一个数位为\(6\),还要跳过\(2\)
然后套上记搜模板就好。

#include<cstdio>
#include<cstring>
using namespace std;
const int N = 10;
int a[N], f[N][2];
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
int dfs(int pos, int pre, int nw, int lm)
{
	if (pos < 0)
		return 1;
	if (!lm && f[pos][nw] > -1)
		return f[pos][nw];
	int i, k = lm ? a[pos] : 9, s = 0;
	for (i = 0; i <= k; i++)
	{
		if ((!(pre ^ 6) && !(i ^ 2)) || !(i ^ 4))
			continue;
		s += dfs(pos - 1, i, i == 6, lm && i == a[pos]);
	}
	if (!lm)
		return f[pos][nw] = s;
	return s;
}
int calc(int x)
{
	int l = 0;
	do
	{
		a[l++] = x % 10;
		x /= 10;
	} while (x > 0);
	return dfs(l - 1, -1, 0, 1);
}
int main()
{
	int n, m;
	memset(f, -1, sizeof(f));
	while (1)
	{
		n = re();
		m = re();
		if (!n && !m)
			return 0;
		printf("%d\n", calc(m) - calc(n - 1));
	}
	return 0;
}

posted on 2018-09-26 19:11  Iowa_Battleship  阅读(107)  评论(0编辑  收藏  举报

导航