【HDU 2089】不要62

http://acm.hdu.edu.cn/showproblem.php?pid=2089

数位dp,参照了打野的博客

预处理出f数组,f[i][j]表示第i位为数字j时的可行的数字总数。

对于区间[l,r],可以用区间[1,r]-[1,l)求得。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int in() {
	int k = 0, fh = 1; char c = getchar();
	for(; c < '0' || c > '9'; c = getchar())
		if (c == '-') fh = -1;
	for(; c >= '0' && c <= '9'; c = getchar())
		k = (k << 3) + (k << 1) + c - '0';
	return k * fh;
}

int f[8][10], digit[10], len;

int cal(int num) {
	len = 0;
	while (num) {digit[++len] = num % 10; num /= 10;}
	digit[len + 1] = 0;
	int ret = 0;
	for(int i = len; i >= 1; --i) {
		for(int j = 0; j < digit[i]; ++j)
			if (j != 4 && !(digit[i + 1] == 6 && j == 2))
				ret += f[i][j];
		if (digit[i] == 4 || (digit[i + 1] == 6 && digit[i] == 2))
			break;
	}
	return ret;
}

int main() {
	f[0][0] = 1;
	for(int i = 1; i <= 7; ++i)
		for(int j = 0; j <= 9; ++j)
			if (j != 4)
				for(int k = 0; k <= 9; ++k)
					if (k != 4 && !(j == 6 && k == 2))
						f[i][j] += f[i - 1][k];
	
	int n, m;
	n = in(); m = in(); if (n > m) swap(n, m);
	while (n != 0 && m != 0) {
		printf("%d\n", cal(m + 1) - cal(n));
		n = in(); m = in(); if (n > m) swap(n, m);
	}
	return 0;
}

现在才学数位dp,←noip滚粗的前兆_(:з」∠)_

posted @ 2016-08-07 17:51  abclzr  阅读(148)  评论(0编辑  收藏  举报