zoukankan      html  css  js  c++  java
  • 递归

    摘要

    本文将主要介绍递归。

    递归

    递归的含义很好理解,就是一个函数调用自身,难就难在如何确定一个题目的递归式,这就需要多刷题了。
    一个完整的递归函数包含两个部分:

    1. 递归式
    2. 递归出口

    以斐波那契数列为例:

    int f(int n){
    	if(n == 1 || n == 2) return 1; // 递归出口
    	return f(n-1) + f(n-2); // 递归式
    }
    

    递归式用来递归计算我们想要得到的值, 递归出口用来结束递归。
    如果没有递归出口,那么就会一直递归下去,就造成了死循环。

    那么什么题会用到递归呢?

    当需要枚举所有的状态时,大部分都可以用递归。
    子问题和原问题求解方式完全相同的,可以用递归。

    举个例子:
    蓝桥杯练习系统 ---计算n阶行列式


    计算n阶行列式

    给定一个N×N的矩阵A,求|A|。

    输入格式:
    第一行一个正整数N。 接下来N行,每行N个整数,
    第i行第j个数字表示A【i】【j】

    输出格式 一行,输出|A|。


    行列式计算规则:

    A11A12…A1n
    A21A22…A2n

    An1An2…Ann

    n==2 : |A| = A11 * A22 - A12*A21

    n > 2 : |A| = (-1)i-1A11|A’ | + (-1)i-1 A12 |A’ | + … + (-1)i-1A1n|A’ |

    其中, A’ 是原矩阵删去第 1 行和第 i 列后构成的新矩阵。

    A B C   
    D E F  = A * E F + B * D F + C * D E
    G H I        H I       G I       G H
    

    所以当n == 2时就是递归出口了, n > 2 递归计算。

    代码:

    import java.io.*;
    
    public class Determinant {
        static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    
        public static int Int(String s) {
            return Integer.parseInt(s); //把()里的内容转换成整数
        }
    
        public static void copy(int[][]A, int[][]A1, int i, int len)throws IOException {
            for (int x=1; x<len; x++) {
                for (int y=0,j=0; j<len; j++) {
                    if (j!=i) {
                        A1[x-1][y++] = A[x][j];   //相当于3*3计算中A * E F  这一步的实现
                    }                             //                 G H
                }
            }
        }
    
        public static int F(int[][]A, int len)throws Exception {
            int res = 0; //保存每个矩阵的|A|
            if (len==1) {
                return A[0][0];
            }
            if (len==2) {
                return A[0][0]*A[1][1]-A[1][0]*A[0][1]; //递归出口
            }
            else {
                int A1[][] = new int[10][10];
                for (int i=0; i<len; i++) {
                    copy(A,A1,i,len);
                    res += Math.pow(-1,i)*A[0][i]*F(A1,len-1);  //递归式,Math.pow(底数,几次方)
                }
            }
            return res;
        }
    
        public static void main(String[] args)throws Exception {
            int n;
            n = Integer.parseInt(in.readLine());
    
            int arr[][] = new int[10][10];
    
            for (int i=0; i<n; i++) {
                String[] s = in.readLine().split(" ");
                for (int j=0; j<n; j++) {
                    arr[i][j] = Int(s[j]);
                }
            }
            out.write(F(arr,n)+"
    ");
            out.flush();
        }
    }
    

    练习题目

    1. 递归实现指数型枚举
    2. 递归实现组合型枚举
    3. 递归实现排列型枚举
    4. n-皇后 问题
    5. 对应答案

    个人感觉上面的题目对于新手来说太暴力了,有些地方很难理解,有能力的可以一天练习1道。博主感觉当时自学编程,是被很多好看的界面和好玩的程序吸引,当真正研究起算法时,感觉还是很需要扎实的数学功底和分析能力,当然最重要的还是努力了。

    然后这是博主看奇淫巧技总结下来的(还会有持续更新):

    入门题目

    1.蓝桥算法(位运算)

    2.蓝桥算法(递归)

  • 相关阅读:
    准备重启blog。。。
    愿我成功省一。
    [LUOGU]P5502 [JSOI2015]最大公约数
    [LUOGU]P3400 仓鼠窝
    [LUOGU]P5149 会议座位
    OI退役记
    新开博客园~~
    1108 模拟赛
    牛客1102
    题解 CF21B 【Intersection】
  • 原文地址:https://www.cnblogs.com/wangzheming35/p/12344766.html
Copyright © 2011-2022 走看看