小Z的 k 紧凑数

在这里插入图片描述


裸的数位dp,但是要注意是否包含前导0的问题,然后每个数字看前一个数字是否可以转移即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline char getc() {
    static char buf[1000000],*p1=buf,*p2=buf;
    return ((p1==p2)&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2))?EOF:*p1++;
}
template <class int_T> inline void read(int_T& x) {
    x=0; char ch=getc();    for (;!(ch>='0'&&ch<='9');ch = getc());
    for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch = getc());
}
int l,r,k,a[20],dp[20][200][10];
int dfs(int pos,int s,int pre,int lim,int head){
	if(!pos)	return 1;
	if(!lim&&!head&&dp[pos][s][pre]!=-1)	return dp[pos][s][pre];
	int up=lim?a[pos]:9,res=0;
	for(int i=0;i<=up;i++){
		if(head||abs(i-pre)<=k)	res+=dfs(pos-1,s+i,i,lim&&i==up,head&&i==0);
	}
	if(!head&&!lim)	dp[pos][s][pre]=res;
	return res;
}
int solve(int x){
	int pos=0;	memset(dp,-1,sizeof dp);
	while(x)	a[++pos]=x%10,x/=10;
	return dfs(pos,0,0,1,1);
}
signed main(){
	cin>>l>>r>>k;
	cout<<solve(r)-solve(l-1);
	return 0;
}
发布了416 篇原创文章 · 获赞 228 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/103928671