小Q十分富有,拥有非常多的硬币,小Q拥有的硬币是有规律的,对于所有的非负整数K,小Q恰好各有两个面值为2^K的硬币,所以小Q拥有的硬币就是1,1,2,2,4,4,8,8,…。小Q有一天去商店购买东西需要支付n元钱,小Q想知道有多少种方案从他拥有的硬币中选取一些拼凑起来恰好是n元(如果两种方案某个面值的硬币选取的个数不一样就考虑为不一样的方案)。
小Q十分富有,拥有非常多的硬币,小Q拥有的硬币是有规律的,对于所有的非负整数K,小Q恰好各有两个面值为2^K的硬币,所以小Q拥有的硬币就是1,1,2,2,4,4,8,8,…。小Q有一天去商店购买东西需要支付n元钱,小Q想知道有多少种方案从他拥有的硬币中选取一些拼凑起来恰好是n元(如果两种方案某个面值的硬币选取的个数不一样就考虑为不一样的方案)。
输入包括一个整数n(1≤n≤10^18),表示小Q需要支付多少钱。注意n的范围。
输出一个整数,表示小Q可以拼凑出n元钱放的方案数。
6
3
Num = int(input()) dp = {0: 0, 1: 1, 2: 2} def dfs(n): if n < 3: return dp[n] else: if n in dp: return dp[n] if n % 2 == 0: # n为偶数时,要么选取0个1,要么选取2个1. dp[n] = dfs(n >> 1) + dfs((n-2) >> 1) return dp[n] else: # n为奇数时,单个1为必选项,转而考虑偶数n-1, dp[n] = dfs((n-1) >> 1) # 此时偶数n-1完全由多个2的k(k>0)次幂相加而成 return dp[n] # 等式两边同除2,解集个数不变,可得转态转移方程 print(dfs(Num))
import sys import math n = int(sys.stdin.readline()) mem = {-1:0,0:1,1:1} def get_num(n): if n in mem: return mem[n] else: m = int(math.log2(n)) ans = get_num(n-2**m) + get_num(2**(m+1)-2-n) mem[n] = ans return ans print(get_num(n))