接下来就是关于数位DP的练习,上来不看别人的解题报告,我选了一道比较简单的题。此题稍微转化一下比上一题不要62还要简单。
这道题需要我们统计数字中含有49的个数,那么我们可以统计不含49的数再减一下就可以了。这样一来就和上一道题几乎一样了。
状态dp[i][j]表示第i为第一位为j所含符合要求的数字数(注意这里是不含49的数)。
程序中预处理出dp数组,然后在用solve计算即可。
代码如下:

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #define ll long long 7 #define LEN 100 8 using namespace std; 9 10 ll dp[LEN][LEN]; 11 12 void init() 13 { 14 memset(dp, 0, sizeof dp); 15 for(int i=0; i<10; i++)dp[1][i] = 1; 16 for(int i=2; i<LEN; i++){ 17 for(int j=0; j<10; j++){ 18 for(int k=0; k<10; k++){ 19 if(k==9 && j==4) continue; 20 dp[i][j]+=dp[i-1][k]; 21 } 22 } 23 } 24 } 25 26 ll solve(ll x){ 27 char str[100] = {0}; 28 ll ret = 0; 29 sprintf(str+1, "%I64d", x); 30 int len = strlen(str+1); 31 for(int i=len; i>=1; i--){ 32 int pos = len+1-i, num = str[pos]-'0'; 33 for(int j=0; j<num; j++){ 34 if(str[pos-1] == '4' && j==9)continue; 35 ret+=dp[i][j]; 36 } 37 if(str[pos-1]=='4' && num == 9)break; 38 } 39 return ret; 40 } 41 42 int main() 43 { 44 // freopen("in.txt", "r", stdin); 45 46 int T; 47 init(); 48 scanf("%d", &T); 49 while(T--){ 50 ll num; 51 scanf("%I64d", &num); 52 ll ans = num+1-solve(num+1); 53 printf("%I64d ", ans); 54 } 55 return 0; 56 }