牛客网 拼凑硬币

拼凑硬币

题目描述:

小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))

转载于:https://www.cnblogs.com/curtisxiao/p/11366164.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值