递归

摘要

本文将主要介绍递归。

递归

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

  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)+"\n");
        out.flush();
    }
}

练习题目

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

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

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

入门题目

1.蓝桥算法(位运算)

2.蓝桥算法(递归)

posted @ 2020-02-22 11:50  我在吃大西瓜呢  阅读(247)  评论(0编辑  收藏  举报