对于学习C语言的一般都知道我们需要练习使用程序求二项式系数。今天我主要给大家分享使用迭代、递归、动态规划求二项式系数,同时分析算法时间空间复杂性。对于迭代和递归的概念,我之前也有讲解,现在呢?给大家讲解一下动态规划的概念。动态规划是五大常用的算法之一,动态规划过程是:每次决策依赖于当前状态。又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这样的多阶段最优化决策解决这个问题的过程就称为动态规划。 动态规划是运筹学中用于求解决策过程中的最优化数学方法 。通常假设问题是由交叠的子问题所构成,我们就能够用动态规划技术来解决它。一般来说,这种子问题出如今对给定问题求解的递推关系中,这个递推关系包括了同样问题的更小子问题的解。动态规划法建议,与其对交叠子问题一次重新的求解,不如把每一个较小子问题仅仅求解一次并把结果记录在表中(动态规划也是空间换时间的)。这样就能够从表中得到原始问题的解。动态规划经常常使用于解决最优化问题。完整代码如下。
迭代程序源代码:
#include<iostream>
using namespace std;
int C(int n,int m)
{
if(m==0 || m==n) return 1;
else return C(n-1,m-1)+C(n-1,m);//迭代算法控制
}
int main()
{
int n,m;
cin>>n>>m;
cout<<C(n,m)<<endl;
return 0;
}
结果:
分析:迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭代的初始值。所以时间复杂度应该就是O(C(n,m)),空间复杂度应该为O(n)。
递归算法计算二项式系数程序代码:
#include<stdio.h>
int f(int n,int k)
{
if(k==0||k==n) //出口
return 1;
else
return f(n-1,k)+f(n-1,k-1);//阶乘
}
void main(){
int n,k,c;
scanf("%d%d",&k,&n);
c=f(n,k);
printf("%d\n",c);
}
结果:
分析:递归就是在运行的过程中调用自己。使用递归解决问题,思路清晰,代码少。但是使用递归算法要耗用更多的栈空间,所以在堆栈尺寸受限制时(如嵌入式系统或者内核态编程。所以该算法的时间复杂度为O(n^2),空间复杂度为O(n)。
动态规划算法计算二项式系数程序代码:
#include <iostream>
#include <cstdlib>
using namespace std;
long Binomial(int,int);
int main()
{
int n,k;
cout<<"输入n:";
cin>>n;
cout<<"\输入k:";
cin>>k;
cout<<"\nC("<<n<<","<<k<<")="<<Binomial(n,k)<<endl;
return 0;
}
int min(int n,int m)
{
return (n>m)?m:n;
}
long Binomial(int n,int k)
{
if (n<k||n<0||k<0)
{
cout<<"数据为:\n";
return -1;
}
else
{
int** a=new int*[n+1];
if (a==0)
{
cout<<"不能分配\n";
return -2;
}
int i,j;
for (i=0;i<=n;i++)
{
a[i]=new int[k+1];
if (a[i]==0)
{
cout<<"不能分配\n";
return -3;
}
}
for (i=0;i<=n;i++)
{
for (j=0;j<=min(i,k);j++)
if (j==0||j==i)
a[i][j]=1;
else
a[i][j]=a[i-1][j]+a[i-1][j-1];
}
int temp=a[n][k];
for (i=0;i<=n;i++)
delete [] a[i];
delete [] a;
return temp;
}
}
结果: