hdu2089 数位dp二(不含62或者4)
递推的写法,进一步理解了数位dp,为了防重复计算总是比当前上限小的。

1 #include<stdio.h> 2 #include<string.h> 3 int dp[10][5],num[10]; 4 int cal(int x) 5 { 6 int tmp=x,i,cnt,ans,flag; 7 memset(num,0,sizeof(num)); 8 cnt=ans=flag=0; 9 while (x!=0) 10 { 11 num[++cnt]=x%10; 12 x/=10; 13 } 14 for (i=cnt;i>=1;i--) 15 { 16 ans+=dp[i-1][2]*num[i]; 17 if (flag) 18 ans+=dp[i-1][0]*num[i]; 19 else{ 20 if (num[i]>4) ans+=dp[i-1][0]; 21 if (num[i+1]==6&&num[i]>2) ans+=dp[i][1]; 22 if (num[i]>6) ans+=dp[i-1][1]; 23 if (num[i]==4||(num[i+1]==6&&num[i]==2)) flag=1; 24 } 25 } 26 if (flag) ans++; 27 return tmp-ans; 28 } 29 int main() 30 { 31 int n,m,i; 32 memset(dp,0,sizeof(dp)); 33 dp[0][0]=1; 34 for (i=1;i<=7;i++) 35 { 36 dp[i][0]=dp[i-1][0]*9-dp[i-1][1]; 37 dp[i][1]=dp[i-1][0]; 38 dp[i][2]=dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0]; 39 } 40 while (~scanf("%d%d",&n,&m)&&n&&m) 41 printf("%d\n",cal(m)-cal(n-1)); 42 }