light oj 1140 - How Many Zeroes? 数位DP

思路:dp[i][j]:表示第i位数,j表示是否有0.

代码如下:

 

 1 #include<iostream>

 2 #include<stdio.h>

 3 #include<algorithm>

 4 #include<iomanip>

 5 #include<cmath>

 6 #include<cstring>

 7 #include<vector>

 8 #define ll long long

 9 #define pi acos(-1.0)

10 #define MAX 50000

11 using namespace std;

12 int bit[22];

13 ll dp[22][2],p[22];

14 ll dfs(int pos,int m,bool f)

15 {

16     if(pos==-1) return !m;

17     if(!f&&dp[pos][m]!=-1) return dp[pos][m];

18     ll ans=0;

19     int e=f?bit[pos]:9;

20     for(int i=0;i<=e;i++){

21         if(i==0&&m){

22             if(!(f&&i==e)) ans+=p[pos]+dfs(pos-1,1,0);

23             else{

24                 ll t=0;

25                 for(int j=pos;j>=0;j--) t=t*10+bit[j];

26                 t++;

27                 ans+=t+dfs(pos-1,1,1);

28             }

29         }

30         else ans+=dfs(pos-1,m||i!=0,f&&i==e);

31     }

32     if(!f) dp[pos][m]=ans;

33     return ans;

34 }

35 ll cal(ll n)

36 {

37     if(n<0) return 0;

38     int m=0;

39     while(n){

40         bit[m++]=n%10;

41         n/=10;

42     }

43     return dfs(m-1,0,1);

44 }

45 int main(){

46     int t,ca=0;

47     ll a,b;

48     p[0]=1;

49     memset(dp,-1,sizeof(dp));

50     for(int i=1;i<22;i++) p[i]=10*p[i-1];

51     scanf("%d",&t);

52     while(t--){

53         scanf("%lld%lld",&a,&b);

54         printf("Case %d: %lld\n",++ca,cal(b)-cal(a-1));

55     }

56     return 0;

57 }
View Code

 

 

 

你可能感兴趣的:(zero)