HYSBZ - 1026 (数位dp)

来源:互联网 发布:淘宝网卖家客服 编辑:程序博客网 时间:2024/05/16 20:31

windy数
Time Limit: 1000MS Memory Limit: 165888KB 64bit IO Format: %lld & %llu

[Submit]   [Go Back]   [Status]  

Description

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

Input

包含两个整数,A B。

Output

一个整数。

Sample Input

【输入样例一】1 10【输入样例二】25 50

Sample Output

【输出样例一】9【输出样例二】20【数据规模和约定】20%的数据,满足 1 <= A <= B <= 1000000 。100%的数据,满足 1 <= A <= B <= 2000000000 。

Source

SCOI2009

[Submit]   [Go Back]   [Status]  

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int MAXN = 10;const int MAXM = 15;int dp[MAXM][MAXN],digit[MAXM],cnt;void init_digits(int x){    cnt = 0;    memset(digit, 0, sizeof(digit));    while (x){        digit[++cnt] = x % 10;        x /= 10;    }}void init(){    memset(dp, 0, sizeof(dp));    for (int i = 0; i < MAXN; ++i)        dp[1][i] = 1;    for (int i = 2; i <= MAXM; ++i)        for (int j = 0; j < MAXN; ++j)            for (int k = 0; k < MAXN; ++k)                if (abs(j - k) >= 2)                    dp[i][j] += dp[i - 1][k];}int solve(int x){    init_digits(x);    int sum = 0;    for (int i = 1; i < cnt; ++i)        for (int j = 1; j < MAXN; ++j)            sum += dp[i][j];    for (int i = 1; i < digit[cnt]; ++i)        sum += dp[cnt][i];    for (int i = cnt - 1; i; --i){        for (int j = 0; j < digit[i]; ++j)            if (abs(digit[i + 1] - j) >= 2)                sum += dp[i][j];        if (abs(digit[i + 1] - digit[i]) < 2)            break;    }    return sum;}void check(int l,int r){    int sum = r - l + 1;    for (int i = l; i <= r; ++i){        init_digits(i);        for (int j = cnt - 1; j; --j)            if (abs(digit[j+1] - digit[j]) < 2){                --sum;                break;            }    }    printf("%d\n", sum);}int l, r;int main(){    init();    while (~scanf("%d %d", &l, &r)){        printf("%d\n",solve(r+1) - solve(l));        //check(l, r);    }    return 0;}





0 0