POJ 3286 How many 0's(数位DP模板)

Posted Yeader

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3286 How many 0's(数位DP模板)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=3286

题目大意:

输入n,m,求[n,m]的所有数字中,0出现的总数是多少,前导零不算。

解题思路:

模板题,设dp[pos][num],pos为数位,num为当前0的数目,然后套数位DP模板即可。

还有之前的一些思考:

关于数位DP求0时,dp下标记录num有什么作用,num不是与后面的0的个数无关吗?
是的,在(!limit&&!lead)的情况下,前面有多少0是不影响后面可以出现多少0的。
但是,比如说dp[pos][num]吧,dp[1][0]=10,但是dp[1][1]=11,这样应该有点明白了吧,
虽然后面有多少0不影响,但是记忆化的结果加上了前面的0的数量num,这样前面的num就
需要当做下标记录下来了,不同的num对应的记忆化结果是不一样的。

代码

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<string>
13 #define lc(a) (a<<1)
14 #define rc(a) (a<<1|1)
15 #define MID(a,b) ((a+b)>>1)
16 #define fin(name)  freopen(name,"r",stdin)
17 #define fout(name) freopen(name,"w",stdout)
18 #define clr(arr,val) memset(arr,val,sizeof(arr))
19 #define _for(i,start,end) for(int i=start;i<=end;i++)
20 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
21 using namespace std;
22 typedef long long LL;
23 const int N=5e6+5;
24 const int INF=0x3f3f3f3f;
25 const double eps=1e-10;
26 
27 LL top[105];
28 LL dp[50][50];
29 
30 LL dfs(bool limit,bool lead,LL pos,LL num){
31     if(pos==-1)
32         return num;
33     if(!limit&&!lead&&dp[pos][num]!=-1) return dp[pos][num];
34     LL up=limit?top[pos]:9;
35     LL ans=0;
36     for(int i=0;i<=up;i++){
37         ans+=dfs(limit&&i==up,lead&&i==0,pos-1,num+(i==0&&!lead));
38     }
39     if(!lead&&!limit) dp[pos][num]=ans;
40     return ans;
41 }
42 
43 LL solve(LL x){
44     memset(dp,-1,sizeof(dp));
45     int cnt=-1;
46     while(x){
47         top[++cnt]=x%10;
48         x/=10;
49     }
50     return dfs(1,1,cnt,0);
51 }
52 
53 int main(){
54     FAST_IO;
55     LL l,r;
56     while(cin>>l>>r){
57         if(l==-1&&r==-1)
58             break;
59         LL ans=0;
60         if(l==0) l++,ans++;    
61         ans+=solve(r)-solve(l-1);
62         cout<<ans<<endl;
63     }
64     return 0;
65 }

 

以上是关于POJ 3286 How many 0's(数位DP模板)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3286 How many 0's(数位DP模板)

UVA - 10061 How many zero&#39;s and how many digits ?

How Many Tables(POJ 1213 求连通分量)

How Many O's? UVA - 11038

hdu 1978 How Many Ways

POJ 2413 How many Fibs?#二分+大数加法