Sweet Snippet 之 骑士金币问题

63 篇文章 1 订阅
21 篇文章 1 订阅

本文简述了骑士金币问题的两种实现方法

首先我们来看下什么是 骑士金币问题:

骑士金币问题

国王要用金币赏赐忠于他的骑士.骑士在就职的第一天得到一枚金币,接下来的两天(第二天和第三天)每天会得到两枚金币,接下来的三天(第四、五、六天)每天会得到三枚金币,接下来的四天(第七、八、九、十天)每天会得到四枚金币,这样的赏赐形式会一直持续下去,问题是给定一个天数(譬如第十天),求骑士将会获得的总的金币数量.

举个简单的例子,如果给定第十天( N N N = 10),那么骑士将会获得的总的金币数量( C C C)为:

C = 1 + 2 + 2 + 3 + 3 + 3 + 4 + 4 + 4 + 4 = 1 + 2 2 + 3 2 + 4 2 = 30 C = 1 + 2 + 2 + 3 + 3 + 3 + 4 + 4 + 4 + 4 = 1 + 2^2 + 3^2 + 4 ^ 2 = 30 C=1+2+2+3+3+3+4+4+4+4=1+22+32+42=30

  • 循环实现

按照题意,我们直接以连续获得相同金币的天数为循环量来累加金币,当然还需要处理一下最后一轮循环天数不足的情况,代码大概是这个样子(Lua)

function golden_coins(target_days)
    local coins = 0
    local cur_coin = 1
    local days = 0
    
    while days + cur_coin <= target_days do
        coins = coins + cur_coin * cur_coin
        days = days + cur_coin
        cur_coin = cur_coin + 1
    end
    
    local remaining_days = target_days - days 
    coins = coins + cur_coin * remaining_days
    
    return coins
end

该实现方法的时间复杂度为 O ( N ) O(\sqrt{N}) O(N )

  • 公式实现

我们也可以直接使用公式来进行求解,主要是要了解以下两个公式:

S 1 = 1 + 2 + 3 + . . . + N = N ( N + 1 ) 2 S 2 = 1 2 + 2 2 + 3 2 + . . . + N 2 = N ( N + 1 ) ( 2 N + 1 ) 6 S1 = 1 + 2 + 3 + ... + N = \frac{N(N + 1)}{2} \\ S2 = 1^2 + 2^2 + 3^2 + ... + N^2 = \frac{N(N + 1)(2N + 1)}{6} S1=1+2+3+...+N=2N(N+1)S2=12+22+32+...+N2=6N(N+1)(2N+1)

骑士金币问题可以认为是已知 S 1 S1 S1 的数值,来求解 S 2 S2 S2 的数值(当然,仍然要处理一下最后一轮循环天数不足的情况),代码大概是这个样子:

function golden_coins_v2(target_days)
    local sq_days = math.floor(0.5 * (-1 + math.sqrt(1 + 8 * target_days)))
    local coins = (sq_days * (sq_days + 1) * (2 * sq_days + 1)) / 6
    local remaining_days = target_days - sq_days * (sq_days + 1) * 0.5
    coins = coins + (sq_days + 1) * remaining_days
    return coins
end

该实现的时间复杂度为 O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值