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 }

 

你可能感兴趣的:(poj)