【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  阅读(...)  评论(... 编辑 收藏