题意:设一个数的十进制表达是 a1a2a3...an ,则它是 Balanced Number 的定义是:存在一个位置 i <=n,使得:
问区间[l,r] 内有多少个数是 Balanced Number;
分析:数位操作,看数据范围可以想到是数位DP,上述 i 也就是中间点,因为数据范围1e<=1e18,所以可以枚举进行数位DP;
设dp[pos][i][sum] 表示在第pos为,中间点为第i位,当前上述公式和为sum;
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
int digit[20];
ll dp[20][20][4000];
ll dfs(int pos,int g,int sum,bool lim){
if(pos==-1) return sum==2000;
if(!lim&&dp[pos][g][sum]!=-1) return dp[pos][g][sum];
int up=lim?digit[pos]:9;
ll res=0;
for(int i=0;i<=up;i++){
res+=dfs(pos-1,g,i*(pos-g)+sum,i==up&&lim);
}
return lim?res:dp[pos][g][sum]=res;
}
ll solve(ll n){
if(n==-1) return 0;
if(n==0 ) return 1;
int pos=0;
while(n){
digit[pos++]=n%10;
n/=10;
}
ll res=0;
for(int i=0;i<pos;i++){
res+=dfs(pos-1,i,2000,1);
}
res-=pos-1; //因为每次枚举0都重复计算了一边,所以减去pos-1个;
return res;
}
int main()
{
memset(dp,-1,sizeof(dp));
int T;
scanf("%d",&T);
while(T--){
ll l,r;
scanf("%lld%lld",&l,&r);
ll ans=solve(r)-solve(l-1);
printf("%lld\n",ans);
}
}