降维打击面试题系列:生成函数(四)部分分式分解

因为组合和错位相减技巧的存在,我们的生成函数总是会面对分母是多项式的生成函数。

一般的组合数学教程不会讲解代数技巧,但对于如我一样数学基础不太好的程序员,求得生成函数之后如何进行化简则是非常关键的。

那么,这一节,我们就来讨论一下如何处理此类分母为多项式的生成函数。

分母带有单根的部分分式分解

我们首先来考虑部分分式问题,我们首先把分母多项式做因式分解,得到如下形式:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G ( x ) = c ( x ) ( x − x 1 ) ( x − x 2 ) . . . ( x − x n ) G(x)=\frac{c(x)}{(x-x_1)(x-x_2)...(x-x_n)} </math>G(x)=(x−x1)(x−x2)...(x−xn)c(x)

作为热身,我们先来考虑 <math xmlns="http://www.w3.org/1998/Math/MathML"> x 1 , x 2 , . . . , x n x_1,x_2,...,x_n </math>x1,x2,...,xn不相等的情况。我们假设部分分式分解后:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> c ( x ) ( x − x 1 ) ( x − x 2 ) . . . ( x − x n ) = a 1 ( x − x 1 ) + a 2 ( x − x 2 ) + . . . . . . + a n ( x − x n ) \frac{c(x)}{(x-x_1)(x-x_2)...(x-x_n)} = \frac{a_1}{(x-x_1)} + \frac{a_2}{(x-x_2)} + ...... + \frac{a_n}{(x-x_n)} </math>(x−x1)(x−x2)...(x−xn)c(x)=(x−x1)a1+(x−x2)a2+......+(x−xn)an

这里 <math xmlns="http://www.w3.org/1998/Math/MathML"> a 1 , a 2 , . . . , a n a_1,a_2,...,a_n </math>a1,a2,...,an必定都是常数。

假设要求 <math xmlns="http://www.w3.org/1998/Math/MathML"> a k a_k </math>ak,我们把等式两边分别乘以 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x − x k ) (x-x_k) </math>(x−xk),可以得到:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> c ( x ) ( x − x 1 ) ( x − x 2 ) . . . ( x − x k − 1 ) ( x − x k + 1 ) . . . ( x − x n ) = a 1 ( x − x k ) ( x − x 1 ) + a 2 ( x − x k ) ( x − x 2 ) + . . . + a k + . . . + a n ( x − x k ) ( x − x n ) \frac{c(x)}{(x-x_1)(x-x_2)...(x-x_{k-1})(x-x_{k+1})...(x-x_n)} = \frac{a_1(x-x_k)}{(x-x_1)} + \frac{a_2(x-x_k)}{(x-x_2)} + ... + a_k +... + \frac{a_n(x-x_k)}{(x-x_n)} </math>(x−x1)(x−x2)...(x−xk−1)(x−xk+1)...(x−xn)c(x)=(x−x1)a1(x−xk)+(x−x2)a2(x−xk)+...+ak+...+(x−xn)an(x−xk)

因为此式两边恒等,所以我们取 <math xmlns="http://www.w3.org/1998/Math/MathML"> x = x k x=x_k </math>x=xk,得到无重根的部分分式分解公式:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> a k = c ( x k ) ( x k − x 1 ) ( x k − x 2 ) . . . ( x k − x k − 1 ) ( x k − x k + 1 ) . . . ( x k − x n ) a_k = \frac{c(x_k)}{(x_k-x_1)(x_k-x_2)...(x_k-x_{k-1})(x_k-x_{k+1})...(x_k-x_n)} </math>ak=(xk−x1)(xk−x2)...(xk−xk−1)(xk−xk+1)...(xk−xn)c(xk)

例题:一般的多项乘积分母

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 1 ( x − 1 ) ( x − 2 ) ( x − 3 ) = a 1 x − 1 + a 2 x − 2 + a 3 x − 3 \frac{1}{(x-1)(x-2)(x-3)} = \frac{a_1}{x - 1} + \frac{a_2}{x - 2} + \frac{a_3}{x - 3} \\ </math>(x−1)(x−2)(x−3)1=x−1a1+x−2a2+x−3a3

求 <math xmlns="http://www.w3.org/1998/Math/MathML"> a 1 , a 2 , a 3 a_1,a_2,a_3 </math>a1,a2,a3。

根据无重根的部分分式分解公式:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> a 1 = 1 ( 1 − 2 ) ( 1 − 3 ) = 1 2 a 2 = 1 ( 2 − 1 ) ( 2 − 3 ) = − 1 a 3 = 1 ( 3 − 1 ) ( 3 − 2 ) = 1 2 a_1 = \frac{1}{(1 - 2)(1 - 3)} = \frac12\\ a_2 = \frac{1}{(2 - 1)(2 - 3)} = -1 \\ a_3 = \frac{1}{(3 - 1)(3 - 2)} = \frac12 </math>a1=(1−2)(1−3)1=21a2=(2−1)(2−3)1=−1a3=(3−1)(3−2)1=21

可用wolfram alpha验证答案正确:www.wolframalpha.com/input?i=%5C...

例题:斐波那契数列

接下来我们不如来试试看用这个公式来求解斐波那契数列的通项公式。

首先,解斐波那契数列的生成函数,前文已经讲过:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G ( x ) = 1 1 − x − x 2 G(x) = \frac{1}{1-x-x^2}\\ </math>G(x)=1−x−x21

我们首先把分母多项式用一元二次方程求根:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G ( x ) = − 1 ( x − 1 − 5 2 ) ( x − 1 + 5 2 ) G(x)=-\frac{1}{(x - \frac{1-\sqrt5}{2})(x - \frac{1+\sqrt5}{2})}\\ </math>G(x)=−(x−21−5 )(x−21+5 )1

接下来我们使用部分分式分解公式,可以得到:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G ( x ) = − 1 + 5 2 − 1 − 5 2 ( x − 1 − 5 2 ) − 1 − 5 2 − 1 + 5 2 ( x − 1 + 5 2 ) G(x)=-\frac{\frac{1+\sqrt5}{2} - \frac{1-\sqrt5}{2}}{(x - \frac{1-\sqrt5}{2})} - \frac{\frac{1-\sqrt5}{2} - \frac{1+\sqrt5}{2}}{(x - \frac{1+\sqrt5}{2})} \\ </math>G(x)=−(x−21−5 )21+5 −21−5 −(x−21+5 )21−5 −21+5

整理后得到:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G ( x ) = − 5 ( x − 1 − 5 2 ) + 5 ( x − 1 + 5 2 ) G(x)= - \frac{\sqrt5}{(x - \frac{1-\sqrt5}{2})} + \frac{\sqrt5}{(x - \frac{1+\sqrt5}{2})} \\ </math>G(x)=−(x−21−5 )5 +(x−21+5 )5

此时我们可以注意到,可以把G(x)分解成两部分 \
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G 1 ( x ) = − 5 ( x − 1 − 5 2 ) G 2 ( x ) = 5 ( x − 1 + 5 2 ) G_1(x)= - \frac{\sqrt5}{(x - \frac{1-\sqrt5}{2})} \\ G_2(x)= \frac{\sqrt5}{(x - \frac{1+\sqrt5}{2})} \\ </math>G1(x)=−(x−21−5 )5 G2(x)=(x−21+5 )5

所以我们斐波那契数列的通项公式为:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G ( x ) = G 1 ( x ) + G 2 ( x ) G(x) = G_1(x) + G_2(x) </math>G(x)=G1(x)+G2(x)

从上一篇文章可知, <math xmlns="http://www.w3.org/1998/Math/MathML"> G 1 ( x ) G_1(x) </math>G1(x) 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> G 2 ( x ) G_2(x) </math>G2(x) 是等比数列的生成函数,其通项公式分别是
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> − 1 5 ( 1 − 5 2 ) n 和 1 5 ( 1 + 5 2 ) n -\frac{1}{\sqrt5}{(\frac{1-\sqrt5}{2})}^n 和 \frac{1}{\sqrt5}{(\frac{1+\sqrt5}{2})}^n </math>−5 1(21−5 )n和5 1(21+5 )n

所以,最终 <math xmlns="http://www.w3.org/1998/Math/MathML"> G ( x ) G(x) </math>G(x)通项公式为:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> − 1 5 ( 1 − 5 2 ) n + 1 5 ( 1 + 5 2 ) n -\frac{1}{\sqrt5}{(\frac{1-\sqrt5}{2})}^n + \frac{1}{\sqrt5}{(\frac{1+\sqrt5}{2})}^n </math>−5 1(21−5 )n+5 1(21+5 )n

结语

通过前面的推导,我们获得了一个处理分母为多项式的生成函数形式的通用思路,但是如果分母多项式含有重根,有复根,甚至根本难以因式分解,是否有办法处理呢?

这些情况我们留待下一小节讨论。

相关推荐
无小道19 分钟前
算法——暴力+优化
算法·优化·暴力
Free Tester24 分钟前
如何判断 LeakCanary 报告的严重程度
java·jvm·算法
zyq99101_11 小时前
DFS算法实战:经典例题代码解析
python·算法·蓝桥杯·深度优先
智者知已应修善业1 小时前
【51单片机单按键切换广告屏】2023-5-17
c++·经验分享·笔记·算法·51单片机
广州灵眸科技有限公司1 小时前
为RK3588注入澎湃算力:RK1820 AI加速卡完整适配与评测指南
linux·网络·人工智能·物联网·算法
qinian_ztc1 小时前
frida 14.2.18 安装报错解决
算法·leetcode·职场和发展
AI应用实战 | RE1 小时前
012、检索器(Retrievers)核心:从向量库中智能查找信息
人工智能·算法·机器学习·langchain
凤年徐1 小时前
C++手撕红黑树:从0到200行,拿下STL map底层核心
c++·后端·算法
Thomas.Sir1 小时前
AI 医疗之罕见病/疑难病辅助诊断系统从算法到实现【表型驱动与知识图谱推理】
人工智能·算法·ai·知识图谱
tankeven2 小时前
动态规划专题(03):区间动态规划从原理到实践(未完待续)
c++·算法·动态规划