求由一种特殊递推关系决定的数列通项

本文介绍了如何通过递推公式求解多项式数列的通项,以等差数列和二次数列为起点,分析通项与多项式次数的关系,并提出利用待定系数法和杨辉三角解决高次多项式数列问题。通过代码展示了如何实现这一过程,包括求解特定位置的杨辉三角值的函数、计算中间值的函数以及求解通项系数的算法。最后给出了完整的C语言代码实现,并进行了结果验证。
摘要由CSDN通过智能技术生成

问题引入:设有一数列,首项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));
}

 以上就是我要分享的全部内容了,觉得还不错的可以点点赞,发发评论,自己动手求一下这些通项公式,验证正不正确。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值