Projecteuler 169

本文探讨了Project Euler 169问题的解决方法,该问题要求计算特定数值下表达方式的数量。通过递归关系式和优化算法,最终得出10^25的情况下的解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[url]http://projecteuler.net/index.php?section=problems&id=169[/url]
[quote]Define f(0)=1 and f(n) to be the number of different ways n can be expressed as a sum of integer powers of 2 using each power no more than twice.

For example, f(10)=5 since there are five different ways to express 10:

1 + 1 + 8
1 + 1 + 4 + 4
1 + 1 + 2 + 2 + 4
2 + 4 + 4
2 + 8

What is f(10^(25))?
[/quote]
注意到
f(2k+1) = f(k)
f(2k) = f(k) + f(k-1) k >= 1
容易得到,对 n = p*2^m(其中p%2==1,m>=0),有:
f(n) = f(p) + m*f(p-1)
因此
f(n+1) = f(p*2^m+1)
= f(p*2^(m-1))
= f(p) + (m-1)*f(p-1)
从而:
x*f(n)+y*f(n+1) = (mx+(m-1)y)f(p-1)+(x+y)f(p)

因此得到下面的代码:
/**
compute x*f(n)+y*f(n+1) where n%2 == 0
*/
def count(x: BigInt, y: BigInt, n: BigInt): BigInt = {
if(n == 0) return x + y
val m = n.lowestSetBit // n = p*2^m where p%2 == 1
val p = n >> m
count(x*m + y*(m-1),x+y,p-1)
}

[quote]scala> count(1,0,(10: BigInt).pow(25))
res1: BigInt = 178653872807
[/quote]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值