牛牛爱66

今天面试了一道算法题,这到算法题我写的有问题,我在这里记录一下。

众所周知,牛牛不喜欢6这个数字(因为牛牛和66发音相近)所以他想知道,不超过n位十进制数中有多少个数字不含有连续的6(从1开始算的)

输入只包含一个正整数n(1<=n<20),输出一个整数,表示不超过n位十进制数中有多少个数字不含有连续的6。

比如输入1,输出10: 1,2,3,4,5,6,7,8,9,10 这十个数字中都满足条件

输入2,输出99,因为只有66不满足条件。

 

分析:

我是用动态规划的方式来写的,首先对于n位数,如果能求出来有多少个数字含有连续6,那么用10^(n) - 这个数字 就可以。

我最开始的思路是有点问题的,在这里记录一下:

假设dp[n]表示的是n位数字的包含连续6的数字总数。那么对于n+1位数来说,相当于在n位数前面加了一位数。假设从xxx变成了axxx(a是新加的最高位数)。我们考虑两种情况,第一种,a!=6的情况:那么当a不是6的时候,相当于这a可以取12345789(6不能取,0也不能取,因为是n+1位数),在这些情况中,原本n位数中有多少连续6的数字,新增了一个不是6的高位数,肯定是不影响结果的,所以首先有dp[n + 1] 首先肯定包括 8*dp[n]。 然后考虑 a = 6的情况:当a= 6时候,考虑次高位也就是第n位数:当次高位是6的时候,那么之后的低位数字无论怎么变,都满足连续6的数字,因为最高位和次高位都是6. 所以还包括了10 ^(n - 1); 当次高位不是6的时候,那么就需要看n-1位数中连续6的数字的个数了(也就是比如说60xx)这种情况中xx所有可能情况中6的个数,而这种情况下的个数应该是9*dp[n - 1]. 所以总的递推关系是 dp[n + 1] = 8 * dp[n] + 9 * dp[n - 1] + 10^(n - 1).

结果最后的结果并不符合面试官的要求,递推公式有问题。面试之后我也一直在想到底是哪里出了问题,现在才想明白。实际上我们要求的是n位数中包括的连续6的数字,而n位数包括了n-1位数,n-2位数等等。什么意思呢,就是说比如60066这个数字是5位数中符合条件的,那么66也算是5位数中符合条件的。具体在递推公式中,也就是当高位不是6的情况下,不仅仅是12345789,而且0也行,当n+1位数为0的时候,这说明是为了添加某一个位数小于n+1的满足条件的数字了。所以实际上递推公式应该是:dp[n + 1] = 9 * dp[n] + 9 * dp[n - 1] + 10^(n - 1). 递归起始条件是dp[1] = 0, dp[2] = 1. 

因为一道题而挂掉了面试,权当在此记录一下自己辛酸的历程吧。

你可能感兴趣的:(算法)