【问题标题】:How to solve this recurrence?如何解决这种复发?
【发布时间】:2013-07-30 19:47:35
【问题描述】:

我有这样的复发f(n)=(2*f(n-1)+2*f(n-2))%10007;

现在我需要找到一个特定的 n:

g(n)=(f(n)f(0)+f(n-1)f(1)+....+f(0)f(n))%10007.

例如如果n=3,

g(3)=(f(3)f(0)+f(2)f(1)+f(1)f(2)+f(0)f(3))%10007.

n 可以大到 10^9。我可以在log(n) 中使用矩阵指数找到f(n) 的值,但我不知道如何获得g(n)

(我需要这个来解决来自amritapuri 2008 regional的问题

【问题讨论】:

  • 这个问题似乎跑题了,因为它是关于数学的。
  • @DavidEisenstat 我不同意。它是关于使用程序解决数学问题。这非常符合主题。
  • @David Eisenstat:“矩阵求幂”是一个编程主题,这是一个编程竞赛的问题。
  • 我碰巧知道如何解决它,这更像是一个组合问题而不是算法问题。
  • f(n)有一个比较简单的公式。查找为什么黄金比例对于斐波那契数列来说是特殊的,然后用这个递归特殊的数字来改变这个公式。

标签: algorithm math recursion recurrence


【解决方案1】:

暂时忘记 10007。

F(x)=sum(f(n)*x^n)。然后F(x)=(f(0)+x*(f(1)-2f(0))/(1-2x-2x^2)

G(x)=sum(g(n)*x^n)。然后G(x)=F(x)^2

因此问题被简化为找到一个系列的系数(模 10007)。

【讨论】:

  • 我不明白...... OP 甚至没有说 f(0) 是什么。如果是0怎么办?那时真的不适合。
  • 不,不是。如果f(1) = 1,其他值不会为0。
  • f(n) 大概是平铺 2 x n 的方法数,忽略拆分的位置,因此 f(0) = 1 和 f(1) = 2。
  • @DavidEisenstat - 我还是不明白。然后F(1) = 1 / 3,也没什么意义。
  • 不应该是.../(1-2x-2x^2)吗?
【解决方案2】:

背景

最初的问题是关于如何用 4 种类型的瓷砖平铺一个 2*n 的矩形。

不同寻常的是,瓷砖必须分成两部分。

提示 1

但是,您也可以将其视为一种方法,将原始的 4 块红色瓷砖和另一组 4 块蓝色瓷砖拼在一起,这样最终的棋盘就有红边和蓝边。

提示 2

令 f(n) 为仅用红色瓷砖平铺 2*n 矩形的方式数,而 h(n) 是用 0 列或更多列红色瓷砖平铺 2*n 矩形的方式数后跟 1 列或多列蓝色瓷砖。

提示 3

您现在可以找到一个简单的矩阵乘法,它根据 h 和 f 的前两个值给出下一个值,并使用标准矩阵幂幂求最终值。

示例代码

这是一个 Python 演示,该公式给出的答案与原始求和相同。

def f(n):
    """Number of ways to tile 2*n board with red tiles"""
    if n<0: return 0
    if n==0: return 1
    return 2*f(n-1)+2*f(n-2)

def g_orig(n):
    """Number of ways to tile 2*n board in two halves"""
    return sum(f(k)*f(n-k) for k in range(n+1))

def h(n):
    """Number of ways to tile 2*n board with red tiles and at least one column of blue tiles"""
    if n<1: return 0
    # Consider placing one column of blue tiles (either 2*1 or 2 1*1)
    t=2*(f(n-1)+h(n-1))
    # Also consider placing two columns of blue tiles (either a 2*2 or L shaped and a 1*1)
    t+=2*(f(n-2)+h(n-2))
    return t

def g(n):
    return f(n)+h(n)

for n in range(10):
    print n,g_orig(n),g(n)

【讨论】:

  • 你为g 的前两个值找到了什么公式?
  • 请注意,g 取决于 g 的前 2 个值和 f 的前 2 个值。
  • 谢谢,这是一个很好的解决方案。
【解决方案3】:

诀窍在于序列f(n) mod 10007 的周期为10007,即f(n) mod 10007 = f(n + 10007) mod 10007。所以你需要做的只是(1)计算f(0 .. n - 1) mod 10007,(2)为0 &lt;= k &lt; 10007计算f(n - k)f(k) mod 10007,然后(3)根据你的方程对它们求和。你甚至不需要幂幂的方法来计算f(n)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多