hdu 3555(数位dp)

接下来就是关于数位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\n", ans);
54     }
55     return 0;
56 }
View Code

 

posted @ 2013-11-23 18:35  张小豪  阅读(159)  评论(0编辑  收藏  举报