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

 

 

 

posted @ 2013-09-13 20:02  _随心所欲_  阅读(492)  评论(0编辑  收藏  举报