题干
传送门
windy 定义了一种 windy 数。
题目描述
不含前导零且相邻两个数字之差至少为 2的正整数被称为 windy 数。windy 想知道,在 a 和 b 之间,包括 a 和 b ,总共有多少个 windy 数?
输入格式
输入只有一行两个整数,分别表示 a 和 b。
输出格式
输出一行一个整数表示答案。
输入输出样例
输入 #1
1 10
输出 #1
9
输入 #2
25 50
输出 #2
20
数位dp入门题,考虑记忆化搜索需要几个参量。
首先基本必有的limit,判上界,zero,判前导0,st,目前第几位。
然后本题因为要求相邻2位绝对值差大于等于2,所以再引入pre,表上一位的值。
然后就当模板打了。
code:
#include<bits/stdc++.h>
using namespace std;
//数位dp st第几位 pre上一位值 li上位是否到上界 zero是否有前导0
//1:不超上界 2:绝对值之差大于2
int l,r,num[11],f[11][11][2][2],len;
int Read()
{
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return f*x;
}
int dfs(int st,int pre,int li,int zero)
{
int sum=0;
if(!st) return 1;
if(f[st][pre][li][zero]) return f[st][pre][li][zero];
for(int i=0;i<=9;i++)
{
if((!li||i<=num[st])&&(abs(i-pre)>=2||zero))
sum+=dfs(st-1,i,i==num[st]&&li,zero&&!i);
}
f[st][pre][li][zero]=sum;
return sum;
}
int part(int x)
{
memset(f,0,sizeof(f));
len=0;
while(x)
{
num[++len]=x%10;
x/=10;
}
return dfs(len,11,1,1);
}
int main()
{
l=Read(),r=Read();
printf("%d",part(r)-part(l-1));
}