BZOJ
luogu
数位dp入门题
复杂度:\(O(11×10×10)\)
详细见注释

#define ll long long
#include<bits/stdc++.h>
using namespace std;
int len,w[11];
ll a,b,f[11][10];
//前导0的bool标记就省掉了,x==-2就表示上一位是前导0
ll dfs(int p,int x,bool lim){//p第几位,x上一位是多少,lim这一位是否受最高位限制
	if(!p)return 1;//搜到一个合法数
	if(!lim&&x!=-2&&f[p][x]!=-1)return f[p][x];//记忆化
	int up=lim?w[p]:9;ll res=0;
	for(int i=0;i<=up;i++){
		if(abs(i-x)<2)continue;
		if(!i&&x==-2)res+=dfs(p-1,-2,lim&&(i==up));//这一位还是前导0
		else res+=dfs(p-1,i,lim&&(i==up));
	}
	return (!lim&&x!=-2)?f[p][x]=res:res;//记忆化
}
ll solve(ll x){
	len=0;
	while(x){w[++len]=x%10;x/=10;}
	return dfs(len,-2,1);
}
int main(){
	cin>>a>>b;
	memset(f,-1,sizeof(f));
	printf("%lld\n",solve(b)-solve(a-1));//前缀相减
	return 0;
}

相关文章:

  • 2022-02-23
  • 2021-10-07
  • 2022-01-29
  • 2021-12-27
  • 2021-07-04
  • 2021-07-19
  • 2021-11-14
猜你喜欢
  • 2021-09-05
  • 2021-06-21
  • 2021-09-16
相关资源
相似解决方案