牛客网 拼凑硬币

∥☆過路亽.° 提交于 2019-11-27 13:44:39

拼凑硬币

题目描述:

小Q十分富有,拥有非常多的硬币,小Q拥有的硬币是有规律的,对于所有的非负整数K,小Q恰好各有两个面值为2^K的硬币,所以小Q拥有的硬币就是1,1,2,2,4,4,8,8,…。小Q有一天去商店购买东西需要支付n元钱,小Q想知道有多少种方案从他拥有的硬币中选取一些拼凑起来恰好是n元(如果两种方案某个面值的硬币选取的个数不一样就考虑为不一样的方案)。

参考了题解中的答案,感叹太强了;
\(recur(n-2^m)\) 代表了使用最大的 \(2^m\)来构建n,这里边需要转换一下思维,我没法直接找使用了\(2^m\)的方法数,
但是这个方法数实际上和构建\((n-2^m)\)的个数是相同的;
\(recur(2**(m+1)-2-n)\) 代表了不使用\(2^m\)来构建n,这个需要这样理解,不使用\(2^m\),说明现在剩了2副\(2^0,\cdots,2^(m-1)\),这里面加起来正好是\(2^(m+1)-2\),同样使用上述思想,便可以表示。只能说,真的太强了;

import sys
import math
 
n = int(sys.stdin.readline())
mem = {-1:0,0:1,1:1}
def recur(n):
    if n in mem:
        return mem[n]
    else:
        m = int(math.log2(n))
        res = recur(n-2**m)+recur(2**(m+1)-2-n)
        mem[n] = res
        return res
print(recur(n))
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!