题目描述
小 Z 在草稿纸上列出了很多数,他觉得相邻两位数字差的绝对值不超过 \(k\) 的整数特别奇特,称其为 \(k\) 紧凑数。
现在小 Z 想知道 \([l,r]\) 内有多少个 \(k\) 紧凑数,希望你帮帮他。
具体思路
首先,要求数的个数,自然想到数位 dp。
然后可以用容斥原理拆询问。
\[ans=\sum_{i=l}^r calc(i)=\sum_{i=1}^r calc(i)-\sum_{i=1}^{l-1} calc(i) \]由于只有一组询问,我们可以采用记忆化搜索的方式来解决本题。
要让相邻两位数字差的绝对值不超过 \(k\),我们只需要在每次搜索时记录上一位数字即可。
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=20;
LL k,f[N][N],a[N];
LL dfs(int pos,int last,int lead,int limit){
if(!pos)return 1;
if(!limit&&!lead&&~f[pos][last])return f[pos][last];
LL res=0,up=limit?a[pos]:9;
for(int i=0;i<=up;i++){
if(lead||abs(i-last)<=k){
res+=dfs(pos-1,i,lead&&!i,limit&&i==up);
}
}
if(!limit&&!lead)f[pos][last]=res;
return res;
}
LL calc(LL x){
int cnt=0;
while(x){
a[++cnt]=x%10;
x/=10;
}
memset(f,-1,sizeof(f));
return dfs(cnt,0,1,1);
}
int main(){
LL l,r;scanf("%lld%lld%lld",&l,&r,&k);
printf("%lld",calc(r)-calc(l-1));
return 0;
}
标签:last,紧凑,int,题解,P2188,pos,limit,calc,LL
From: https://www.cnblogs.com/reclusive2007/p/17761858.html