• 有关递推与递归的回顾


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

    递推

    联系&难度

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

    例题

    斐波那契数列

    这是一道最基础的递推题,根据对数列的描述,不难发现,从第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 完成编辑

    日后优化持续跟进

  • 相关阅读:
    16 pymysql模块的使用
    15 可视化工具 Navicat的简单使用
    14 补充 MySQL的创建用户和授权
    13 多表查询
    linux常用查看文件或日志命令
    linux查找大文件命令
    linux测试环境维护之磁盘空间维护
    linux配置IP访问权限
    通过pytty工具代理连接数据库mysql(绕开数据库白名单限制)
    redis安装详解
  • 原文地址:https://www.cnblogs.com/Dfkuaid-210/p/12900626.html
Copyright © 2020-2023  润新知