c++编程提升之路第一课——递推

目录

一:前言

二:递推

        例题一:永生的兔子

                题目

                思路

                做法一

                做法二

                做法三

                要点

        例题二:分平面

                题目

                思路

                做法一

                 做法二

                做法三

                要点

        递推要点总结


一:前言

        现在开始,作者要写一些提高编程水平的博客了,希望大家可以从中获取一些知识。喜欢的朋友也可以点个关注啦~

二:递推

        递推是一种算法,它是由一个数组来进行的:首先给数组的一些特殊位置赋上初值,之后的每一个值都可以由之前的值得到,这就叫递推。

        例题一:永生的兔子

                题目

题目介绍:

修罗王在恐怖的冥界中找到了传说的不死秘术。为了安全起见,他对一对刚出生的小兔子施展了此魔法。现在假设秘术使得所有的兔子都不死,而且兔子在出生2个月后,就有生殖能力。每一对有繁殖能力的兔子可以生殖一对兔子。那么n个月,繁殖了多少对兔子?(n<=50)

输入格式

一个整数,表示n个月的时候

输出格式

一个整数,表示n个月的时候一共有多少兔子

输入样例 复制

3

输出样例 复制

2

                思路

我们先定义一个a数组,表示第i个月共有a[i]只兔子,那么a[1]和a[2]都应该等于1。后边的公式怎么推到呢?我们先来画个图。

                如图可知,第i个月的兔子数量就是大兔子数量+小兔子数量,这个月的大兔子数量就是上个月的总兔子数量(因为上个月的小兔子已经成年了,变成大兔子了。所以也就是上个月的兔子遗留下来的),这个月的小兔子数量其实就是上个月的大兔子生的,所以,就是上个月的大兔子数量。我们推出了公式:这个月的兔子数量=上个月的兔子数量+上个月的大兔子数量

                做法一

                        用两个数组分别存放这个月的兔子数量和这个月的大兔子数量~

                        上个月的大兔子数量其实就是上个月的总兔子数量

#include <bits/stdc++.h>
using namespace std;
int main(){
	long long n;
	cin>>n;
	if(n<3){//特判
		cout<<1;
		return 0;
	}
	long long a[n+1];//总共的兔子数量 
	long long b[n+1];//大兔子数量 
	a[1]=1,a[2]=1;
	b[1]=1,b[2]=1;
	for(long long i=3;i<=n;i++){
		b[i]=a[i-1];//保存这个月的大兔子数量
		a[i]=a[i-1]+b[i-1];//累加
	}
	cout<<a[n];//输出结果
	return 0;
}

                做法二

                        上个月的大兔子数量其实就是上上个月的兔子数量

                        所以,只要一个数组来进行操作就行了。

#include <bits/stdc++.h>
using namespace std;
int main(){
	long long n;
	cin>>n;
	if(n<3){//特判 
		cout<<1;
		return 0;
	}
	long long a[n+1];//用来保存兔子数量 
	a[1]=1,a[2]=1;//保存初值
	for(long long i=3;i<=n;i++)//循环 
	a[i]=a[i-1]+a[i-2];
	cout<<a[n];//输出结果 
	return 0;
}

                做法三

                        根据代码我们可以得知:每次我们使用的都是当前的数据和前两次的数据,如果定义一个数组有点费空间,所以,我们可以用三个变量来进行操作。这种方法叫迭代

#include <bits/stdc++.h>
using namespace std;
int main(){
	long long n;
	cin>>n;
	if(n<3){//特判 
		cout<<1;
		return 0;
	}
	long long a,b,c;//定义三个变量 
	a=b=1;//保存初值
	for(int i=3;i<=n;i++){//循环 
		c=a+b;
		a=b;
		b=c;//迭代 
	}
	cout<<c;//输出结果 
	return 0;
}

                要点

1:开始时要写特判

2:给数据保存初值

3:数组或变量要用long long(因为题目说n<=50,用int会爆掉)

        例题二:分平面

                题目

题目描述

一条直线可以把一个平面分成2个面。2条直线,可以最多把一个平面分成4个平面,那么请问:n条直线,最多能把平面分成几个面?

输入格式

一个整数,表示一共有几条直线

输出格式

一个整数,表示可以分割成最多面的数量

输入样例 复制

3

输出样例 复制

7

                思路

                        这道题需要转换思想,首先我们用a[i]表示第i条线可以把一张纸分成a[i]个面。

                        然后列一下初值

f[0]=1;

f[1]=2;

                        然后画个图(这是三条横线的样子)

                        再画一条线,我们可以发现,最多可以经过三条线,所以能增加三个平面,而且多出一条线还可以增加一条平面,所以可以增加四个平面,而这正好是第四条线。

                因此,我们可以得出规律:a[i]=a[i-1]+i;(这个需要更多的推算,此处省略~)

                做法一

                        上面我们已经得出了规律,再加上之前得出的初值,一个代码就完成了!

#include <bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a[n+1];
	if(n==0){//特判 
		cout<<1;
		return 0;
	}
	a[0]=1;//赋初值 
	a[1]=2;
	for(int i=2;i<=n;i++)
	a[i]=a[i-1]+i;//运算 
	cout<<a[n];
	return 0;
}

                 做法二

                        我们可以发现,i从2开始循环,直到n结束,每次都是加上i,而初值又是2,可以理解为1+(1+2+...+n-1+n)的和

#include <bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a=1;
	for(int i=1;i<=n;i++)
	a+=i;//运算 
	cout<<a;
	return 0;
}

                做法三

                        这个做法其实就是一个数学公式完成!

#include <bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	cout<<1+(n+1)*n/2;
	return 0;
}

                        乍一看,刚开始觉得题目特别难,现在,一个公式就完成了,这种方法还是需要大家多去推敲推敲的。

                要点

1:开始记得写特判(做法三不用)

2:推导过程需要大家多去回顾,多加思考

        递推要点总结

第一步:先列一些初值

第二步:画图来推导公式,需要反复验证(也可以多列一些初值,根据数字找规律)

第三步:根据初值和公式实现代码

第四步:根据代码进行优化,可以优化时间,也可以优化空间。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值