windy数 【数位DP】

来源:互联网 发布:js数组增加一个元素 编辑:程序博客网 时间:2024/06/10 11:28

windy数

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

windy定义了一种windy数。

不含前导零且相邻两个数字之差至少为22的正整数被称为windy数。

windy想知道,在AABB之间,包括AAB

B,总共有多少个windy数?



#pragma comment(linker, "/STACK:102400000,102400000") 
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
#include <queue>
#define Pi acos(-1.0)
using namespace std;


typedef long long  ll;
ll DP[20][10][3];
int DIG[20];
ll  dfs(int pos,int pre,int limit,int judge)
{
    if(pos < 0)
        return   1;
    if(!limit && DP[pos][pre][judge] != -1)
        return    DP[pos][pre][judge];
    int   end = limit ? DIG[pos] : 9;
    ll    ret = 0;
    
    if(judge == 0){
    ret += dfs(pos-1,0,0,0);
    for(int i = 1;i <= end;i++){
    ret += dfs(pos-1,i,0,1);
   }
    }
    else{
    for(int i = 0;i <= end;i ++){
    if(abs(pre-i) < 2 && judge) continue; 
ret += dfs(pos - 1,i,limit && (i == end),1);
    }
    }
    


        


    //DP里保存完整的、取到尽头的数据
    if(!limit)
        DP[pos][pre][judge]= ret;


    return    ret;
}
ll slove(ll x){
ll tem = x;
memset(DP,-1,sizeof DP);
int num = 0;
while(x){
DIG[num] = x%10;
x/=10;
num++;
}
ll ans = 0;
ans += dfs(num-2,0,0,0);
for(int i = 1;i <= DIG[num-1];i++) 
ans += dfs(num-2,i,i==DIG[num-1],1);
return ans;

}
int main(){
ll n, m;
int t;




while(~scanf("%lld%lld",&n, &m)){

printf("%lld\n", slove(m) - slove(n-1));

/*
for(int i = 1;i <= 300;i++){
printf(" %d = %lld\n", i,slove(i) - slove(i-1));
}*/
}


0 0