BZOJ1026 [SCOI2009] windy数

Description

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

Input

  包含两个整数,A B。

Output

  一个整数


还算是一道标准的数位dp,不过使用递归完成数位dp的注意了,因为在同为零的情况下,数字零会有首位与非首位的区别,为了这个wa点本弱debug了一个多小时。

还有就是本弱犯的第二个错误,把首位的零直接当作-2处理,其实倒没啥,问题在于,dp[len][-2]是什么鬼东西嘛....

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
typedef long long ll;
ll num[100];
ll dp[100][10][10];
int lenx;
ll dfs(int len,ll digit,ll flag,bool first)
{
	if(!len) return 1;
	if(!flag&&dp[len][first][digit]!=-1) return dp[len][first][digit];
	ll maxn=flag?num[len]:9;
	ll ans=0;
	for(int i=0;i<=maxn;i++)
	{
		if(i==0&&first) ans+=dfs(len-1,0,flag&&i==maxn,1);
		else if(first) ans+=dfs(len-1,i,flag&&i==maxn,0);
		else if(abs(i-digit)>=2)
		{
			ans+=dfs(len-1,i,flag&&i==maxn,0);
		}
	}
	if(!flag) dp[len][first][digit]=ans;
	return ans;
}
ll calc(ll x)
{
	lenx=0;
	while(x)
	{
		num[++lenx]=x%10;
		x/=10;
	}
	return dfs(lenx,0,1,1);
}
int main()
{
	int m,n;
	memset(dp,-1,sizeof(dp));
	scanf("%lld %lld",&n,&m);
	//for(int i=0;i<20;i++)
	//printf("%lld %lld\n",calc(m),calc(n-1));
	//printf("%lld %lld\n",calc(m),calc(n-1));
	printf("%lld\n",calc(m)-calc(n-1));
	return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值