题目描述
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?
输入输出格式
输入格式:
包含两个整数,A B。
输出格式:
一个整数
输入输出样例
输入样例#1:
1 10
输出样例#1:
9
输入样例#2:
25 50
输出样例#2:
20
说明
100%的数据,满足 1 <= A <= B <= 2000000000 。
前导零的意思我理解了半天结果是这样的,在普通的数位dp时候
例如你计算10,那么会枚举00,01,02,03.。。10
这时候的01应该当成1来处理而不是01(01不符合,而1就符合了)
本来想着开一个二维dp,结果超时,我又不会剪枝优化,那就开三维了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[12][12][12];
int a[12];
ll dfs(int len,int last,int zero,int limit)
{
if(len==0) return 1;
if(!limit && dp[len][zero][last]!=-1) return dp[len][zero][last];
int cur = 0, up = limit?a[len]:9;
for(int i=0;i<=up;i++)
{
if(!zero && last!=-1 && abs(i-last)<2)
continue;
cur += dfs(len-1,i,zero && !i,limit && i==a[len]);
}
return limit?cur:dp[len][zero][last] = cur;
}
ll cmp(ll x,ll y)
{
int c[12],d[12];
int pos1, pos2;
pos1 = pos2 = 0;
while(x)
c[++pos1]=x%10,x/=10;
while(y)
d[++pos2]=y%10,y/=10;
while(pos1<pos2)
c[++pos1]=0;
for(int i=0;i<=pos1;i++)a[i]=c[i];
memset(dp,-1,sizeof(dp));
ll ans = dfs(pos1,-1,1,1);
for(int i=0;i<=pos2;i++)a[i]=d[i];
memset(dp,-1,sizeof(dp));
ans = dfs(pos2,-1,1,1)-ans;
return ans;
}
int main()
{
ll a,b;
scanf("%lld%lld",&a,&b);
printf("%lld\n",cmp(a-1,b));
return 0;
}