windy数 (数位dp)

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

输入格式
  包含两个整数,A B。

输出格式
  一个整数

数据范围和提示
【数据规模和约定】

100%的数据,满足 1 <= A <= B <= 2000000000 。

Sample Input
【输入样例一】
1 10

【输入样例二】

25 50
Sample Output
【输出样例一】

9

【输出样例二】

20

分析:

dp[i][j]:i表示数位,j表示当前位的前一位上的数字。
注意要加上前导零的判断,只有当前位的前一位不是前导零且两者之差小于2的可以跳过

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+10;
int a[30];
ll dp[30][10];
ll dfs(int pos,int lead,int flag,int num)
{ 
	if(pos<1) 
	{
		return 1;
	}
	if(!flag&&!lead&&dp[pos][num]!=-1) 
	{
		return dp[pos][num]; 
	}
	int up=flag?a[pos]:9;
	ll res=0;
	for(int i=0;i<=up;i++)
	{
		if(!lead&&abs(num-i)<2) continue;
		res+=dfs(pos-1,lead&&i==0,flag&&i==a[pos],i);
	}
	if(!flag&&!lead) 
	{
		dp[pos][num]=res;
	}
	return res;
}
ll solve(ll x)
{
	int k=0;
	while(x)
	{
		a[++k]=x%10;
		x/=10;
	}
	return dfs(k,1,1,0);
}
int main()
{
	ll a,b;
	scanf("%lld%lld",&a,&b);
	memset(dp,-1,sizeof(dp));
	printf("%lld",solve(b)-solve(a-1));
	return 0;
} 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值