【HDOJ】【2089】不要62
数位DP
cxlove基础数位DP第一题
用容斥把所有的不吉利数字去掉就得到吉利数字的数量= =(满足区间减法)
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 }