问题引入:设有一数列,首项A1=1,有A(n+1)=A(n)+f(n)(f(n)是一个多项式),求通项公式。
问题举例:当f(n)=2时,f(n)为0次多项式,显然A(n)是一个等差数列,其通项为A(n)=2*n-1。当f(n)=2*n+1时,f(n)为1次多项式,中学常做到的一种题目,用累加法很容易得出A(n)=n^2。
问题分析: 观察问题举例当中的两个例子,我们能够发现A(n)也是一个多项式而且其次数为f(n)的次数加1。有了这个基础之后我们就能够用待定系数法去求得通项了。
问题求解:若f(n)为m次多项式,那么其就可以用其系数表示,用一个长度为m+1的数组储存起来,记为XS[m+1],那么A(n)就为m+1次多项式,用一个长度为m+2的数组储存起来,记为an[m+2],这就是待定系数。f(n)是题目给出,即XS[m+1]已知,求解数组an[m+2]。用题目中给的那个递推公式,就可以联立方程解出系数an[m+2]。
代码实现:还是上面那个例子,若f(n)=2*n+1,设A(n)=A*n^2+B*n+C,那A(n+1)=A*(n+1)^2+B*(n+1)+C。列出方程就可以得到一下方程组。
再用相同的方法提高次数到3,可以发现方程组左边化的系数矩阵为
可以发现它是一个5列的杨辉三角,当然也不是所有的数
都能用上,但对于求解问题定然有所帮助。
首先,我们需要一个求杨辉三角某行某列的值的函数Fyh,用到递归。很简单,不细说,上代码。
double Fyh(int h,int l)
{
if(l==1 || l==h+1)
return 1;
else
return Fyh(h-1,l-1)+Fyh(h-1,l);
}
接着就是求an[m+2],稍作分析,我们可以得到,an[0]=XS[0] / Fyh(m+1,2),an[1]=(XS[1]-Fyh(m+1,3)) / Fyh(m,2)......为了方便,我们可以再定义一个中间函数mid用于求XS后要减掉的数,因为其规律比较明显,跟an的下标和f(n)的次数有关系,代码比我说的好理解。
double mid(double array[],int k,int n)
{
int i;
double s=0;
if(k==0){
return 0;
}else{
int hh=n-k+1;
int ll=3;
int xx=k-1;
for(i=1;i<=k;i++){
s += Fyh(hh++,ll++)*array[xx--];
}
}
return s;
}
array传入系数数组,k是下标,n是f(n)的次数。
mid定义好之后,一个关系就很容易写出来了an[k] = (XS[k]-mid(array,k,n)) / Fyh(n-k,2)。再将其用代码的方式表达出来,一个for循环就可以求得所有的系数了。
下面上完整代码以及一些结果。
#include<stdio.h>
#include<math.h>
#define N 10
double Fyh(int h,int l); //求斐波那契数列函数
void OUT(double *an,double *XS,int n); //输出函数
double mid(double array[],int k,int n); //中间值函数
double JY(double *XS,int k,int n); //递归函数求数列值
void JYHS(double *XS,double *an,int n); //检验函数
int main()
{
int n;
printf("?次多项式:");
scanf("%d",&n);
n++;
double XS[n];
double an[n+1];
for(int i=0;i<n;i++){
scanf("%lf",&XS[i]);
}
OUT(an,XS,n);
for(int i=0;i<n;i++){
printf(" %lfx^%d +",an[i],n-i);
}
printf(" %lf\n",an[n]);
JYHS(XS,an,n);
return 0;
}
double Fyh(int h,int l)
{
if(l==1 || l==h+1)
return 1;
else
return Fyh(h-1,l-1)+Fyh(h-1,l);
}
void OUT(double *an,double *XS,int n)
{
int i;
double array[n+1];
double s=0;
for(i=0;i<n+1;i++){
array[i] = 0;
}
int nn=n;
for(i=0;i<n;i++){
an[i] = (XS[i]-mid(array,i,n)) / Fyh(nn--,2);
array[i] = an[i];
s += an[i];
}
an[n] = 1-s;
}
double mid(double array[],int k,int n)
{
int i;
double s=0;
if(k==0){
return 0;
}else{
int hh=n-k+1;
int ll=3;
int xx=k-1;
for(i=1;i<=k;i++){
s += Fyh(hh++,ll++)*array[xx--];
}
}
return s;
}
double JY(double *XS,int k,int n)
{
int i;
double s=0;
if(k==1){
return 1;
}else{
for(i=0;i<n;i++){
s += XS[i]*pow(k-1,n-i-1);
}
return (JY(XS,k-1,n) + s);
}
}
void JYHS(double *XS,double *an,int n)
{
int i;
double s=0;
for(i=0;i<n+1;i++){
s += an[i] * pow(N,n-i);
}
printf("通项值:%lf\n",s);
printf("递归值:%lf\n",JY(XS,N,n));
}
以上就是我要分享的全部内容了,觉得还不错的可以点点赞,发发评论,自己动手求一下这些通项公式,验证正不正确。