題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=3555php
題目大意是讓你求出[1,n]中多少個數包含49;ios
1.dp[len][0] 表明數字長度爲len不含49的個數 git
2.dp[len][1] 表明數字長度爲len不含49可是以9開頭的個數(顯然dp[len][1]包含在dp[len][0]中)ide
3.dp[len][2] 表明數字長度爲len含有49的個數spa
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 __int64 dp[22][3]; 5 int digit[22]; 6 7 void Initiate(){ 8 dp[0][0]=1; 9 for(int i=1;i<21;i++){ 10 dp[i][0]=10*dp[i-1][0]-dp[i-1][1]; // 在dp[i-1][0]前面添上0~9,可是要減去dp[i-1][1] 由於4和9構成49 11 dp[i][1]=dp[i-1][0]; // 直接在dp[i-1][0]前面添上9就好了 12 dp[i][2]=10*dp[i-1][2]+dp[i-1][1]; // 在dp[i-1][2]前面添上0~9,或者在dp[i-1][1]前面添上4 13 } 14 } 15 16 17 int main(){ 18 int _case; 19 scanf("%d",&_case); 20 Initiate(); 21 while(_case--){ 22 __int64 n; 23 scanf("%I64d",&n); 24 memset(digit,0,sizeof(digit)); 25 int len=1; 26 while(n){ 27 digit[len++]=n%10; 28 n/=10; 29 } 30 bool flag=false; 31 __int64 ans=0; 32 for(int i=len-1;i>=1;i--){ 33 ans+=dp[i-1][2]*digit[i]; 34 if(flag){ 35 ans+=dp[i-1][0]*digit[i]; 36 }else if(digit[i]>4){ 37 ans+=dp[i-1][1]; 38 } 39 if(digit[i+1]==4&&digit[i]==9){ 40 flag=true; 41 } 42 } 43 //推出循環時若是flag==true,則ans++,覺得此時末兩位正好是49 44 if(flag) 45 ans++; 46 printf("%I64d\n",ans); 47 } 48 return 0; 49 }