题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089
数位DP的入门题,我是根据kuangbin的博客写出来的
思路:
dp[i][0],表示长度为i,不存在不吉利数字
dp[i][1],表示长度为i,不存在不吉利数字,且最高位为2
dp[i][2],表示长度为i,存在不吉利数字
然后一层循环即可,主要是自己要能搞懂状态之间的关系
代码如下:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 using namespace std; 6 int dp[10][3]; 7 int bit[10]; 8 void init() 9 { 10 dp[0][0]=1;dp[0][1]=0;dp[0][2]=0; 11 for(int i=1;i<=6;i++) 12 { 13 dp[i][0]=dp[i-1][0]*9-dp[i-1][1]; 14 dp[i][1]=dp[i-1][0]; 15 dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1]; 16 } 17 } 18 int solve(int n) 19 { 20 int len=1; 21 int tmp=n; 22 while(n) 23 { 24 bit[len++]=n%10; 25 n=n/10; 26 } 27 bit[len]=0; 28 int ans=0; 29 bool flag=0; 30 for(int i=len;i>=1;i--) 31 { 32 ans+=dp[i-1][2]*bit[i]; 33 if(flag) ans+=dp[i-1][0]*bit[i]; 34 35 if(!flag && bit[i]>4) ans+=dp[i-1][0]; 36 if(!flag && bit[i+1]==6 && bit[i]>2) ans+=dp[i][1]; 37 if(!flag && bit[i]>6) ans+=dp[i-1][1]; 38 if(bit[i]==4 ||(bit[i+1]==6 && bit[i]==2)) flag=true; 39 40 } 41 if(flag ) ans++; 42 return tmp-ans; 43 } 44 int main() 45 { 46 init(); 47 int n,m; 48 while(scanf("%d%d",&n,&m)!=EOF) 49 { 50 if(n==0 && m==0 ) break; 51 printf("%d ",solve(m)-solve(n-1)); 52 53 } 54 return 0; 55 }