學習連結 https://www.luogu.com/article/tzeo544s
數位DP標準模版:
ll dfs(int pos,int pre,int st,……,int lead,int limit)//記搜
{
if(pos>len) return st;//剪枝
if((dp[pos][pre][st]……[……]!=-1&&(!limit)&&(!lead))) return dp[pos][pre][st]……[……];//記錄當前值
ll ret=0;//暫時記錄當前方案數
int res=limit?a[len-pos+1]:9;//res當前位能取到的最大值
for(int i=0;i<=res;i++)
{
//有前導0並且當前位也是前導0
if((!i)&&lead) ret+=dfs(……,……,……,i==res&&limit);
//有前導0但當前位不是前導0,當前位就是最高位
else if(i&&lead) ret+=dfs(……,……,……,i==res&&limit);
else if(根據題意而定的判斷) ret+=dfs(……,……,……,i==res&&limit);
}
if(!limit&&!lead) dp[pos][pre][st]……[……]=ret;//當前狀態方案數記錄
return ret;
}
ll part(ll x)//把數按位拆分
{
len=0;
while(x) a[++len]=x%10,x/=10;
memset(dp,-1,sizeof dp);//初始化-1(因為有可能某些情況下的方案數是0)
return dfs(……,……,……,……);//進入記搜
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&l,&r);
if(l) printf("%lld",part(r)-part(l-1));//[l,r](l!=0)
else printf("%lld",part(r)-part(l));//從0開始要特判
}
return 0;
}