题意:求小于n的不含49的数的个数
0:不含49;1:不含49,9开头;2:含49
dp[i][0]=dp[i-1][0]*10-dp[i-1][1]; 不含49的数字前加任意数-9开头的数前加4
dp[i][1]=dp[i-1][0]; 不含49的数字前加9
dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; 含49的数前加任意数 9开头的数前加4
View Code
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 #define LL long long 6 int main() 7 { 8 LL dp[25][3]; 9 memset(dp,0,sizeof(dp)); 10 dp[0][0]=1; 11 for(int i=1;i<=20;i++) 12 { 13 dp[i][0]=dp[i-1][0]*10-dp[i-1][1]; 14 dp[i][1]=dp[i-1][0]; 15 dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; 16 } 17 int T; 18 scanf("%d",&T); 19 while(T--) 20 { 21 unsigned LL n; 22 scanf("%I64u",&n); 23 n++; 24 int d[25],len=0; 25 while(n) {d[++len]=n%10; n/=10;} 26 d[len+1]=0; 27 LL ans=0; 28 bool flag=false; 29 for(int i=len;i>0;i--) 30 { 31 ans+=dp[i-1][2]*d[i]; 32 if(flag) ans+=dp[i-1][0]*d[i]; 33 else if(d[i]>4) ans+=dp[i-1][1]; 34 if(d[i+1]==4 && d[i]==9) flag=true; 35 } 36 printf("%I64d\n",ans); 37 } 38 return 0; 39 }