其他分享
首页 > 其他分享> > windy数 (数位dp)

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;
} 

标签:return,int,ll,pos,windy,dp,数位
来源: https://blog.csdn.net/qq_45928501/article/details/113784068