1 条题解
-
0
自动搬运
来自洛谷,原作者为

夏色祭
**搬运于
2025-08-24 21:34:56,当前版本为作者最后更新于2018-01-13 11:09:56,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
楼上题解好鬼畜。
数位dp模板题啊。
我们可以把答案拆成query(1,r)-query(1,l-1)。
那么我们只要求出1~x的这个区间的k紧凑数的数量就行了。
f[i][j]表示第i位上的数为j的k紧凑数的数量。
对于统计就是先统计最高位比x小的方案数,然后再逐位统计。
例如query(1,432)=query(1,399)+query(400,429)+query(430,432)
然后把符合条件的加上就行了。
代码:
#include<cstdio> #include<algorithm> #include<string> #include<set> #include<vector> #include<map> #include<cmath> #define For(i,x,y) for (int i=(x);i<=(y);i++) #define Dow(i,x,y) for (int i=(x);i>=(y);i--) #define cross(i,k) for (int i=first[k];i;i=last[i]) #define il inline #define vd void #define ll long long using namespace std; il ll read(){ ll x=0;int ch=getchar(),f=1; while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar(); if (ch=='-'){f=-1;ch=getchar();} while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } ll l,r,n,f[20][10],num[20],len; //il int abss(int x){return x?x:-x;} il vd dp(){ For(i,0,9) f[1][i]=1; For(i,2,20) For(j,0,9) For(k,0,9) if (abs(j-k)<=n) f[i][j]+=f[i-1][k]; } il ll query(ll x){ len=0; For(i,0,20) num[i]=0; while (x>0){ num[++len]=x%10; x/=10; } ll ans=0; For(i,1,len-1) For(j,1,9) ans+=f[i][j]; Dow(i,len,1){ For(j,0,num[i]-1){ if (i==len&&!j) continue; if (abs(num[i+1]-j)<=n||i==len) ans+=f[i][j]; } if (abs(num[i]-num[i+1])>n&&i!=len) break; } return ans; } int main(){ l=read(),r=read(),n=read(); dp(); return printf("%lld",query(r+1)-query(l)),0; }
- 1
信息
- ID
- 1182
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者