posts - 200,  comments - 0,  trackbacks - 0

BZOJ传送门

洛谷传送门


解析:

由于数据范围很小(相对于大部分数位DPDP题来说)。
我们只记录当前位,当前位数字,是否是前导0,是否达到上界。
简单DP记忆化搜索一下就好了。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline
int getint(){
	re int num;
	re int c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
	return num;
}

int len,mark[12];
int f[12][10][2][2];

inline
int dp(int pos,int num,bool pre0,bool limit){
	if(pos>len)return 1;
	if(~f[pos][num][pre0][limit])return f[pos][num][pre0][limit];
	int res=0;
	int r;
	if(limit)r=mark[pos];
	else r=9;
	for(int re i=0;i<=r;++i){
		if(pre0||abs(i-num)>=2)
		res+=dp(pos+1,i,pre0&&i==0,limit&&i==r);
	}
	return f[pos][num][pre0][limit]=res;
}

inline
int solve(int a){
	memset(f,-1,sizeof f);
	len=0;
	do{
		mark[++len]=a-a/10*10;
		a/=10;
	}while(a);
	reverse(mark+1,mark+len+1);
	return dp(1,0,1,1);
}

signed main(){
	int l=getint(),r=getint();
	cout<<(solve(r)-solve(l-1));
	return 0;
}
posted on 2018-09-29 09:47  zxyoi_dreamer  阅读(...)  评论(... 编辑 收藏