数位DP
模板题
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 }
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 }
练手
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 }

浙公网安备 33010602011771号