数位DP

1.[SCOI2009] windy 数

模板题

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline int read()
 4 {
 5     int x=0;char c=getchar();
 6     for(;!isdigit(c);c=getchar());
 7     for(;isdigit(c);c=getchar()) x=x*10+c-'0';
 8     return x;
 9 } 
10 int a,b;
11 int dp[12][12],s[12];
12 inline int dfs(int now,int pre,int up,int oo)  
13 {
14     if(now==0) return 1;
15     if(!up&&dp[now][pre]!=-1) return dp[now][pre];
16     int maxn=up?s[now]:9;
17     int res=0;
18     for(int i=0;i<=maxn;i++)
19     {
20         if(abs(i-pre)<2) continue;
21         if(oo&&i==0) res+=dfs(now-1,-5,0,1);
22         else res+=dfs(now-1,i,(up&&i==maxn),0);
23     }
24     if(!up&&!oo) dp[now][pre]=res; 
25     return res;
26 }
27 inline int part(int x)
28 {
29     int tot=0;
30     while(x)
31     {
32         s[++tot]=x%10;x/=10;
33     }
34     memset(dp,-1,sizeof(dp));
35     return dfs(tot,-5,1,1);
36 }
37 int main()
38 {
39     a=read();b=read();
40     printf("%d\n",part(b)-part(a-1));
41     return 0;
42 }
View Code

 2.[USACO06NOV] Round Numbers S

模板题

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline int read()
 4 {
 5     int x=0;char c=getchar();
 6     for(;!isdigit(c);c=getchar());
 7     for(;isdigit(c);c=getchar()) x=x*10+c-'0';
 8     return x;
 9 } 
10 int l,r;
11 int dp[35][35][35];
12 int s[35];
13 inline int dfs(int now,int num1,int num0,int up,int oo)//正维护第i位,已经维护好之前1(num1),0(num0)个数,up:1->等于:0->小于,oo是否具有前导0 
14 {
15     if(num1-num0>now) return 0;
16     if(now==0) return 1;
17     if(!up&&dp[now][num1][num0]!=-1) return dp[now][num1][num0];
18     int maxn=up?s[now]:1;
19     int res=0;
20     for(int i=0;i<=maxn;i++)
21     {
22         if(i==0) res+=dfs(now-1,num1,num0+(oo!=1),(up&&i==maxn),(oo>0));
23         if(i==1) res+=dfs(now-1,num1+1,num0,(up&&i==maxn),0);
24     }
25     if(!up&&!oo) dp[now][num1][num0]=res;
26     return res;
27 }
28 
29 int part(int x)
30 {
31     int tot=0;
32     while(x)
33     {
34         s[++tot]=x&1;
35         x>>=1; 
36     }
37     memset(dp,-1,sizeof(dp));
38     return dfs(tot,0,0,1,1);
39 }
40 
41  
42 int main()
43 {
44     l=read();r=read();
45     printf("%d",part(r)-part(l-1));
46     return 0;
47 }
View Code

 3.B-number

练手

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline int read()
 4 {
 5     int x=0;char c=getchar();
 6     for(;!isdigit(c);c=getchar());
 7     for(;isdigit(c);c=getchar()) x=x*10+c-'0';
 8     return x;
 9 } 
10 int dp[15][15][15];
11 int s[15];
12 inline int dfs(int now,int pre,int mod,int up) //pre:1->前为1,2->前有13 
13 {
14     if(now==0)
15     {
16         if(!mod&&pre==2) return 1;
17         else return 0;
18     }
19     if(!up&&dp[now][pre][mod]!=-1) return dp[now][pre][mod];
20     int maxn=up?s[now]:9;
21     int res=0;
22     for(int i=0;i<=maxn;i++)
23     {
24         if((pre==1&&i==3)||pre==2) res+=dfs(now-1,2,(mod*10+i)%13,(up&&i==maxn));
25         else if(i==1) res+=dfs(now-1,1,(mod*10+i)%13,(up&&i==maxn));
26         else res+=dfs(now-1,0,(mod*10+i)%13,(up&&i==maxn));
27     } 
28     if(!up) dp[now][pre][mod]=res;
29     return res;
30 }
31 
32 int part(int x)
33 {
34     int tot=0;
35     while(x)
36     {
37         s[++tot]=x%10;
38         x/=10;
39     }
40     memset(dp,-1,sizeof(dp));
41     return dfs(tot,0,0,1);
42 }
43 int main()
44 {
45     int n;
46     while(~scanf("%d",&n)&&n)
47     {
48         printf("%d\n",part(n));    
49     }
50     return 0;
51 }
View Code

 

 

 

 

 

 

 

posted @ 2020-07-29 19:09  SuYongkang  阅读(91)  评论(0)    收藏  举报