数位DP

cxlove基础数位DP第一题

用容斥把所有的不吉利数字去掉就得到吉利数字的数量= =(满足区间减法)

【HDOJ】【2089】不要62_#include【HDOJ】【2089】不要62_#define_02
 1 //HDOJ 2089
 2 #include<cmath>
 3 #include<vector>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define rep(i,n) for(int i=0;i<n;++i)
10 #define F(i,j,n) for(int i=j;i<=n;++i)
11 #define D(i,j,n) for(int i=j;i>=n;--i)
12 #define pb push_back
13 using namespace std;
14 int getint(){
15     int v=0,sign=1; char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
17     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
18     return v*sign;
19 }
20 const int N=1e6+10,INF=~0u>>2;
21 const double eps=1e-8;
22 /*******************template********************/
23 int dp[10][3];
24 void init(){
25     memset(dp,0,sizeof dp);
26     dp[0][0]=1;
27     F(i,1,6){
28         dp[i][0]=dp[i-1][0]*9-dp[i-1][1];
29         dp[i][1]=dp[i-1][0];
30         dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1];
31     }
32 }
33 int solve(int n){
34     int len=0,bit[10];
35     int tmp=n;
36     for(;n;n/=10) bit[++len]=n%10;
37     bit[len+1]=0;
38     int ans=0;
39     bool flag=false;
40     D(i,len,1){
41         ans+=dp[i-1][2]*bit[i];
42         if (flag) ans+=dp[i-1][0]*bit[i];
43         if (!flag && bit[i]>4) ans+=dp[i-1][0];
44         if (!flag && bit[i+1]==6 && bit[i]>2) ans+=dp[i][1];
45         if (!flag && bit[i]>6) ans+=dp[i-1][1];
46         if (bit[i]==4 || (bit[i+1]==6 && bit[i]==2)) flag=true;
47     }
48     return tmp-ans;
49 }
50         
51 int main(){
52 #ifndef ONLINE_JUDGE
53 //    freopen("input.txt","r",stdin);
54 //    freopen("output.txt","w",stdout);
55 #endif
56     init();
57     int n,m;
58     while(scanf("%d%d",&n,&m)!=EOF && n)
59         printf("%d\n",solve(m+1)-solve(n));
60     return 0;
61 }
View Code