题目传送门:http://codeforces.com/contest/1036/problem/C
数位dp模板题,打round的时候没还没学过digitDP,之后学了一下。
我学习内容不爱啃题解,看文字(比较懒)。所幸b站上有数位dp的教学视频,感谢up主!
https://www.bilibili.com/video/av27156563?from=search&seid=11660223199142447984
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<map> #include<vector> #define INF 2e9 using namespace std; int digit[30]; long long dp[30][4];//dp[i][j]代表一个i位数,不是0的数小于等于3-j个数的数量 long long dfs(int pos,bool limit,int non_zero_number){//the amount of digits that has non-zero value 【从最高位到pos这一位】 if(non_zero_number==4) return 0;//要在pos==0前面 if(pos==0) return 1;//it is a classy number if( !limit && dp[pos][non_zero_number]!=-1 ) return dp[pos][non_zero_number]; long long temp=0; int upper_bound=limit?digit[pos]:9; for(int i=0;i<=upper_bound;i++){ temp+=dfs(pos-1,limit&&(i==upper_bound),non_zero_number+(i!=0)); } if( !limit ) dp[pos][non_zero_number]=temp; return temp; } long long solve(long long num){//classy number in 0-num int k=0; memset(dp,-1,sizeof(dp)); while(num){ digit[++k]=num%10; num/=10; } long long c=dfs(k,true,0); // cout<<c<<endl; return c; } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ long long l,r; cin>>l>>r; cout<<solve(r)-solve(l-1)<<endl; } return 0; }