美文网首页
[a,b]不包含49的数的个数

[a,b]不包含49的数的个数

作者: 小幸运Q | 来源:发表于2021-04-02 17:03 被阅读0次

https://blog.csdn.net/weixin_43701790/article/details/98379811


以1234为例,s=[1,2,3,4]

将区间1 ~ 581按上限拆开,分成1 ~ 499(百位数字小于5)、500 ~ 579(百位为5,十位数字小于8)、580(百位为5,十位是8,个位小于1)和581分成四个部分,以次计算每一个区间求和即可。(注意,581实际在for循环中不会处理,要在for循环后面补一个判断"49")

初始化

f 代表前面[0,i-1]位有没有49,res计算49的个数

dp[i][0] 不含49且开头不是9
dp[i][1] 不含49且开头是9
dp[i][2] 含49

dp[0][0]=1
# dp[1][0]=9
# dp[1][1]=1

for i in range(1,65):
    # 8是因为首位不能是4或者9
    dp[i][0]=int(dp[i-1][0])*9+int(dp[i-1][1])*8
    dp[i][1]=int(dp[i-1][1])+int(dp[i-1][0])
    dp[i][2]=int(dp[i-1][2])*10+int(dp[i-1][1])

dfs判断

以第i位对应的s[i]=a为例:

无论s[i],f的值如何如果第i位取[0,a-1],那么不受限情况下,res+=dp[len-i][2]*a

如果第i位取a,那么受限情况下,res+=dp[len-i][2],如果a>4,那么还得加上右侧头部为9的情况即 res+=dp[len-i][1](如果 a==9,而且前面的第i-1位是4,那么f=true

剩下的部分默认前面的位都取到了上限(比如1234->1xyz,12xy),因为第一位为0的已经dp得到所有解了。所以后面只要解决分拆后的12xy即可。

# 暴力法用于验证
def bloom(n):
    counts=0
    for i in range(int(n)+1):
        if "49" in str(i):
            counts+=1
    return counts
# 数值dp
def dfs(n,dp):
    # res记录各个位49的个数
    res=0
    # 记录之前的i位是否有49
    f=False
    for i in range(len(n)):
        res+=int(n[i])*dp[len(n)-1-i][2]
        if f:
            res+=(dp[len(n)-1-i][1]+dp[len(n)-1-i][0])*(int(n[i]))
            # 坚持不求各位上的上界最大值 1234->12xx不求,只求11xx,10xx
        elif n[i]>"4":
            # 58 -> 49 上界大于4当然可以有49
            res+=dp[len(n)-1-i][1]
        # elif n[i]=="4":
        # 坚持不求各位上的上界最大值
        #     if i+1<len(n) and n[i+1]=="9":
        #         res+=dp[len(n)-1-i][1]
        if n[i]=="9" and (i-1>=0 and n[i-1]=="4"):
            f=True
    if "49" in n:
        res+=1
    return res

# dp[i][0] 不含49且开头不是9
# dp[i][1] 不含49且开头是9
# dp[i][2] 含49
dp=[]
for i in range(65):
    dp.append([0,0,0])

dp[0][0]=1
# dp[1][0]=9
# dp[1][1]=1

for i in range(1,65):
    # 8是因为首位不能是4或者9
    dp[i][0]=int(dp[i-1][0])*9+int(dp[i-1][1])*8
    dp[i][1]=int(dp[i-1][1])+int(dp[i-1][0])
    dp[i][2]=int(dp[i-1][2])*10+int(dp[i-1][1])

n="49419"

print(dfs(n,dp),bloom(n))

相关文章

  • [a,b]不包含49的数的个数

    https://blog.csdn.net/weixin_43701790/article/details/983...

  • T1-4第四题三角形能否成立问题HDU - 2039 amc第一

    Input输入数据第一行包含一个数M,接下有M行,每行一个实例,包含三个正数A,B,C。其中A,B,C <1000...

  • 编程笔试-美丽的数字

    题目 小A有两个幸运数字字符a和b。他认为一个数很美当且仅当这个数字只包含字符a和b,且这个数字没位数字之和也只包...

  • LeetCode 1877. 数组中最大数对和的最小值

    题目 一个数对 (a,b) 的 数对和 等于 a + b 。最大数对和 是一个数对数组中最大的 数对和 。 比方说...

  • golang实现剑指offer:动态规划题型

    丑数 LeetCode 面试题49:丑数 题目描述 我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Nu...

  • Python算术运算符

    + 加 - 两个对象相加a + b 输出结果 30- 减 - 得到负数或是一个数减去另一个数a - b 输出结...

  • 《编程珠玑》第一章

    案例:一个最多包含n个正整数的磁盘文件,每个数都小于n,其中n=10^7,文件中不包含重复的数。要求输出按升序排列...

  • 参数传递的方式

    def # 求任意三个数的乘积 def mul (a,b,c): print(a * b * c) # 根...

  • 丑数

    题目49:丑数 我们把只包含因子2、3 和5 的数称作丑数(Ugly Number)。求从小到大的顺序的第1500...

  • 791. 合并数字

    给出n个数,现在要将这n个数合并成一个数,每次只能选择两个数a,b合并,每次合并需要消耗a+b的能量,输出将这n个...

网友评论

      本文标题:[a,b]不包含49的数的个数

      本文链接:https://www.haomeiwen.com/subject/zbkahltx.html