6338. 猴子碰撞的方法数

185 阅读1分钟

题目:
你有 k 个背包。给你一个下标从 0 开始的整数数组 weights ,其中 weights[i] 是第 i 个珠子的重量。同时给你整数 k 。

请你按照如下规则将所有的珠子放进 k 个背包。

  • 没有背包是空的。
  • 如果第 i 个珠子和第 j 个珠子在同一个背包里,那么下标在 i 到 j 之间的所有珠子都必须在这同一个背包中。
  • 如果一个背包有下标从 i 到 j 的所有珠子,那么这个背包的价格是 weights[i] + weights[j] 。

一个珠子分配方案的 分数 是所有 k 个背包的价格之和。

请你返回所有分配方案中,最大分数 与 最小分数 的 差值 为多少

算法:
方法一:快速幂
总共移动次数2^n次,减去不碰撞的次数2次。需要求出2^n并求余,即求(2^n-2)%mod 满足结合率:2^n % mod - 2 % mod。
通过快速幂求2^n:
用到了求余结合律:(a * b)% mod = a % mod * b % mod % mod

var mod = 1000000007
func monkeyMove(n int) int {
    return (powAndMod(2, n) - 2 + mod) % mod
}
func powAndMod(a, b int) int {
    ans := 1
    for b > 0 {
        if b & 1 == 1 {
            ans = ans * a % mod
        }
        a = a * a % mod
        b = b >> 1
    }
    return ans
}