ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

有关递推与递归的回顾

2020-05-16 17:57:08  阅读:243  来源: 互联网

标签:ch 递归 回顾 int cin ++ include now 递推


注:本文为回顾,所以仅会记录本人认为的难点与分析

递推

联系&难度

个人认为,递推与动态规划实际是密不可分的,你说它简单,但到了做题时难以找到转移方程,你要是说它难,但它确确实实是最基本的东西了

例题

斐波那契数列

这是一道最基础的递推题,根据对数列的描述,不难发现,从第3项开始,我们都可以用这样一个式子表示:\(f_i=f_{i-1}+f_{i-2}\)
因而,我们可以直接利用循环得到,代码如下:

#include <iostream>
#include <cstdio>
using namespace std;
int n,a,b[1000001],mmax = 2;
int main(){
	cin >> n;
	b[1] = 1;
	b[2] = 1;
        for (int i = 3;i <= 1000001;i ++)
	  b[i] = (b[i - 1] + b[i - 2]);
	while (n > 0){
		n --;
		cin >> a;
		cout << b[a] << endl;
	}
	return 0;
}

题目传送门:点这里

上台阶

这一道题其实可以看做一道最基础的动态规划,每一步有3个状态,我们可以发现,当楼梯有1层时,仅有1种走法;当楼梯有2层时,有2种走法:走2个1层或1个2层;当楼梯有3层时,有4种走法:一次三层,三次一层,2、1和1,2;再往后,我们可以发现,i层时可行方法为i-1层i-2层i-3层的方法数总和,即\(f_i=f_{i-1}+f_{i-2}+f_{i-3}\),而\(f_1=1,f_2=2,f_3=4\)为边界条件,进行循环,按输入得到结果即可,代码如下:

#include <iostream>
#include <cstdio>
using namespace std;
long long int n,f[72];
int main(){
	f[1] = 1;
	f[2] = 2;
	f[3] = 4;
        for (int i = 4;i <= 71;i ++)
          f[i] = f[i - 1] + f[i - 2] + f[i - 3];
	while (1){
		cin >> n;
		if (n == 0)
		  break;
		cout << f[n] << endl;
	}
	return 0;
}

题目传送门:点这里

流感传染

这一道题则就是一种搜索,其实并没有太大的难度
具体细节详见下方代码:

#include <iostream>
#include <cstdio>
using namespace std;
int n,t[101][101],o[101][101],m,ch[10001][2],last,now,ans; //o在本处并无实际用处,ch为队列,ch[x][0]为行,ch[x][1]为列,last,now分别为队列的头和尾
int main(){
	cin >> n;
	for (int i = 0;i < n;i ++)
	  for (int j = 0;j < n;j ++){
	  	char c;
	  	cin >> c;
	  	if (c == '.')
	  	  t[i][j] = 0;
	  	else if (c == '@'){
	  		o[i][j] = t[i][j] = 1;
		  }
	  	else if (c == '#')
	  	  o[i][j] = t[i][j] = -1;
	  }  //原图的输入
	cin >> m;
	for (int k = 2;k <= m;k ++){ //需从第二天开始进行模拟
		for (int i = 0;i < n;i ++)
		  for (int j = 0;j < n;j ++)
		    if (t[i][j] == 1){ //如果该点为感染者
		    	if (i - 1 >= 0)    //保证不越界
		    	  if (t[i - 1][j] == 0){ //若该点为正常人
		    	    ch[now][0] = i - 1;  //存储坐标
		    	    ch[now][1] = j;
		    	    now ++; //队尾++
			  }
		    	if (j - 1 >= 0)    //同上
		    	  if (t[i][j - 1] == 0){
		    	    ch[now][0] = i;
		    	    ch[now][1] = j - 1;
		    	    now ++;
			  }
			if (t[i + 1][j] == 0){
		    	  ch[now][0] = i + 1;
		    	  ch[now][1] = j;
		    	  now ++;
			  }
			if (t[i][j + 1] == 0){
		    	  ch[now][0] = i;
		    	  ch[now][1] = j + 1;
		    	  now ++;
			}
		}
		for (int i = last;i < now;i ++){
		    t[ch[i][0]][ch[i][1]] = 1;  //将队列所做更改写入图
		}
		last = now;//清空队列
	}
	for (int i = 0;i < n;i ++)   //统计
	  for (int j = 0;j < n;j ++)
	    if (t[i][j] == 1)
	      ans ++;
	cout << ans ;
	return 0;
}

题目传送门:点这里

递归(搜索与回溯)

联系&难度

搜索与回溯,即深度优先搜索(DPS),属于递归的一种,而且,许多递推可做的题目同样可用递归做出,如:斐波那契数列

例题

八皇后问题

这一道题可以说是十分基础了,基本是必会的题目,主体思想很简单,从第一个皇后的位置进行选择,然后依次判断此行每个位置是否可以放下,如果是,进行递归,如果不行,判断下一位置,然后进行回溯

#include<iostream>
#include<cstdio>
using namespace std;
int a[30];
int b[30];
int c[30];
int d[30];
int flag=0;
void print()
{
    flag++;
    cout<<"No. "<<flag<<endl;
    for(int i=1;i<=8;i++)
    {
        for(int j=1;j<=8;j++)
        {
            if(a[j]==i)
                cout<<"1 ";
            else
                cout<<"0 ";
        }
        cout<<endl;
    }
}
void searchh(int i)
{
    for(int j=1;j<=8;j++)
    {
        if((!b[j])&&(!c[i+j])&&(!d[i-j+7]))
        {
            a[i]=j;
            b[j]=1;
            c[i+j]=1;
            d[i-j+7]=1;
            if(i==8) print();
            else searchh(i+1);
            b[j]=0;
            c[i+j]=0;
            d[i-j+7]=0;
        }
    }
}
int main()
{
    searchh(1);
    return 0;
}

题目传送门:点这里

更新日志

  • 2020.5.16 完成编辑

日后优化持续跟进

标签:ch,递归,回顾,int,cin,++,include,now,递推
来源: https://www.cnblogs.com/Dfkuaid-210/p/12900626.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有