算法设计与分析---第二章 递推算法

递推法特点是:一个问题的求解需一系列的计算,在已知条件和所求问题之间总存在着某种相互联系的关系,在计算时,如果可以找到前后过程之间的数量关系(即递推式),那么,从问题出发逐步推到已知条件,此种方法叫逆推。无论顺推还是逆推,其关键是要找到递推式。
例1】数字三角形。如下所示为一个数字三角形。请编一个程序计算从顶到底的某处的一条路径,使该路径所经过的数字总和最大。只要求输出总和。  
1、 一步可沿左斜线向下或右斜线向下走;  
2、 三角形行数小于等于100;
3、 三角形中的数字为0,1,…,99; 测试数据通过键盘逐行输入,如上例数据应以如下所示格式输入:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在这里插入图片描述
【算法分析】此题解法有多种,从递推的思想出发,设想,当从顶层沿某条路径走到第i层向第i+1层前进时,我们的选择一定是沿其下两条可行路径中最大数字的方向前进,为此,我们可以采用倒推的手法,设a[i][j]存放从i,j 出发到达n层的最大值,则a[i][j]=max{a[i][j]+a[i+1][j],a[i][j]+a[i+1][j+1]},a[1][1] 即为所求的数字总和的最大值。

#include<iostream> 
using namespace std; 
int main() 
{   
	int n,i,j,a[101][101];   
	cin>>n;
	for (i=1;i<=n;i++)    
		for (j=1;j<=i;j++)      
			cin>>a[i][j];                             
	for (i=n-1;i>=1;i--)    
		for (j=1;j<=i;j++)
		{      
			if (a[i+1][j]>=a[i+1][j+1]);
				a[i][j]+=a[i+1][j];    
			else  
				a[i][j]+=a[i+1][j+1];      
		}    
		cout<<a[1][1]<<endl;  
}

例2】满足F1=F2=1,Fn=Fn-1+Fn-2的数列称为斐波那契数列(Fibonacci),它的前若干项是1,1,2,3,5,8,13,21,34……求此数 列第n项(n>=3)。
即:f1=1 (n=1)
f2=1 (n=2)
fn=fn-1 + fn-2 (n>=3)

#include<iostream> 
#include<cstdio> 
using namespace std; 
int main() 
{     
	int f0=1,f1=1,f2;     
	int n;     
	cin>>n;
	for (int i=3; i<=n; ++i)     
	{          
		f2=f0+f1;          
		f0= f1;          
		f1=f2;     
	} 
	printf("%d\n",f2); 
	return 0; 
} 

例3】 有 2χn的一个长方形方格,用一个1*2的骨牌铺满方格。
在这里插入图片描述
编写一个程序,试对给出的任意一个n(n>0), 输出铺法总数。
下面是输入n,输出x1~xn的c++程序:

#include<iostream> 
using namespace std; 
int main() 
{   
	int n,i,j,a[101];   
	cout<<"input n:";                       
	cin>>n;
	a[1]=1;a[2]=2;   
	cout<<"x[1]="<<a[1]<<endl;   
	cout<<"x[2]="<<a[2]<<endl;   
	for (i=3;i<=n;i++)                   
	{
		a[i]=a[i-1]+a[i-2];      
		cout<<"x["<<i<<"]="<<a[i]<<endl;     
	} 
} 

例4】昆虫繁殖
【问题描述】 科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。每对成虫过x个月产y对卵,每对卵要过两个月长成成虫。假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后的第一个月不产卵(过X个月产卵),问过Z个月以后,共有成虫多少对?0=<X<=20,1<=Y<=20,X=<Z<=50
【输入格式】 x,y,z的数值
【输出格式】 过Z个月以后,共有成虫对数
【输入样例】 1 2 8
【输出样例】 37

#include<iostream> 
using namespace std; 
int main() 
{   
	long long a[101]={0},b[101]={0},i,j,x,y,z;   
	cin>>x>>y>>z;
	for(i=1;i<=x;i++){a[i]=1;b[i]=0;}   
		for(i=x+1;i<=z+1;i++)              
		{     
			b[i]=y*a[i-x];     
			a[i]=a[i-1]+b[i-2];             }
		cout<<a[z+1]<<endl;   
		return 0; 
}		

例5】位数问题
【问题描述】 在所有的N位数中,有多少个数中有偶数个数字3?由于结果可能很大,你只需要输出这个答案对12345取余的值。
【输入格式】 读入一个数N
【输出格式】 输出有多少个数中有偶数个数字3。
【输入样例】 2
【输出样例】 73
【数据规模】 1<=N<=1000
【样例说明】 在所有的2位数字,包含0个3的数有72个,包含2个3的数有1个,共73个

#include<iostream> 
using namespace std; 
int main() 
{   
	int f[1001][2],n,i,x;   
	cin>>n;
	f[1][1]=1;f[1][0]=9;                           
	for(i=2;i<=n;i++)     
	{          
		x=f[1][0];       
		if(i==n)
			x--;
		f[i][0]=(f[i-1][0]*x+f[i-1][1])%12345;       
		f[i][1]=(f[i-1][1]*x+f[i-1][0])%12345;       
	}    
	cout<<f[n][0];     
	return 0; 
}
发布了48 篇原创文章 · 获赞 25 · 访问量 2453

猜你喜欢

转载自blog.csdn.net/qq_43628959/article/details/105061314