POJ 3286 How many 0's?(数位DP)

题目链接

终于过了,边界让我wa了好几次,猥琐的用AC代码对拍,很无奈,用非常麻烦的方法。写一下,估计以后再碰到,肯定看不懂这是写的什么了。

以前做过,统计1和2的,统计0比1和2麻烦多了,有前导0的情况,不太好弄。

算是用统计方法,先把sp[len-1]所有的加上,长度为len-1的情况。

然后就是长度为len的情况。从高位到低位,遍历。

如果此位是0,judge(str+1) + 1 + dfs(str+1),是统计当前为是0的,多少情况,但是会漏解,算是受以前那个题统计1和2的影响把。

如果下一位是0,那么就不用管了,交给下位统计去把。下位不是0,计算会漏掉下位是0的情况,所以定住下位是0,组合一下长度len-2的所有0的个数。

不是0的情况,类似。

以前那个题的题解http://www.cnblogs.com/naix-x/archive/2013/03/12/2955544.html

完全没有策略,乱写,乱搞过的。。。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <string>
 5 using namespace std;
 6 #define LL __int64
 7 LL dp[201],sp[201],o[201];
 8 LL judge(char *str)
 9 {
10     int i,len;
11     LL ans;
12     len = strlen(str);
13     ans = 0;
14     for(i = 0; i <= len-1; i ++)
15     {
16         ans = (ans*10 + str[i]-'0');
17     }
18     return ans;
19 }
20 LL dfs(char *str)
21 {
22     int len;
23     LL sum;
24     len = strlen(str);
25     if(len == 1)
26         return 1;
27     sum = (len-1)*o[len-2];
28     if(str[0] == '0')
29     {
30         if(str[1] == '0')
31             return judge(str+1) + 1 + dfs(str+1);
32         else if(len >= 3)
33             return judge(str+1) + 1 +dfs(str+1)+o[len-2] + (len-2)*o[len-3];
34         else
35             return judge(str+1) + 1 + dfs(str+1);
36     }
37     else
38     {
39         if(str[1] == '0')
40             return (str[0]-'1')*sum + dfs(str+1);
41         else if(len >= 3)
42             return (str[0]-'1')*sum + dfs(str+1)+o[len-2] + (len-2)*o[len-3];
43         else
44             return (str[0]-'1')*sum + dfs(str+1);
45     }
46 }
47 LL fun(LL x)
48 {
49     int i,len;
50     char str[201];
51     if(x == 0) return 1;
52     else if(x < 0) return 0;
53     len = 0;
54     while(x)
55     {
56         str[len++] = x%10+'0';
57         x = x/10;
58     }
59     for(i = 0; i < len/2; i ++)
60     {
61         swap(str[i],str[len-i-1]);
62     }
63     str[len] = '\0';
64     return sp[len-1] + dfs(str);
65 }
66 int main()
67 {
68     int i;
69     LL temp = 1,x,y;
70     dp[1] = 1;
71     sp[1] = 1;
72     o[1] = 10;
73     o[0] = 1;
74     for(i = 2; i <= 15; i ++)
75     {
76         dp[i] = (i-1)*9*temp;
77         sp[i] = sp[i-1] + dp[i];
78         o[i] = 10*o[i-1];
79         temp = temp*10;
80     }
81     while ( scanf("%I64d%I64d",&x,&y) && (y>=0) )
82     {
83         printf("%I64d\n",fun(y)-fun(x-1));
84     }
85     return 0;
86 }

 

posted @ 2013-08-09 21:08  Naix_x  阅读(365)  评论(0编辑  收藏  举报