【BZOJ1026】【SCOI2009】windy数

Description

windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?

Input

包含两个整数,A B。

Output

一个整数。

Sample Input1

1 10

Sample Output1

9

Sample Input2

25 50

Sample Output2

20

Hint

100%的数据,满足$ 1\leq A \leq B \leq 2*10^{9}$ 。

Solution

数位DP,用\(f_{i,j}\)表示i位数,最高位为j的情况,容易得出DP方程为\(f_{i,j}=\Sigma_{k} f_{i-1,k} (|k-j| \leq 2)\).

Code

#include <stdio.h>
#define MN 15
#define R register
int a,b,f[MN][MN],q[MN];
void init(){
	for (R int i=0; i<10; ++i) f[1][i]=1;
	for (R int i=2; i<11; ++i)
		for (R int j=0; j<10; ++j)
			for (R int k=0; k<10; ++k)
				if (j-k>1||k-j>1)
					f[i][j]+=f[i-1][k];
}
int get(int x){
	if (!x) return 0;R int res=0,k=0;
	while(x){q[++k]=x%10;x/=10;}
	for (R int i=1; i<k; ++i) 
		for (R int j=1; j<10; ++j)
	    	res+=f[i][j];
	for (R int i=1; i<q[k]; ++i)
		res+=f[k][i];
	for (R int i=k-1; i; --i){
        for (R int j=0; j<q[i]; ++j)
        	if (j-q[i+1]>1||q[i+1]-j>1)
        		res+=f[i][j];
		if (q[i+1]-q[i]>1||q[i]-q[i+1]>1){
			if (i==1) ++res;
			continue;
		}break;
    }return res;
}
int main(){
	init();scanf("%d %d",&a,&b);
	printf("%d",get(b)-get(a-1)); 
	return 0;
}
posted @ 2017-09-19 17:03  Melacau  阅读(136)  评论(0编辑  收藏  举报