蓝桥杯JAVA版答案——2020校内选拔赛——第九题

更多JAVA版答案移步我的博客:蓝桥杯JAVA版答案汇总

题目

小明想知道,满足以下条件的正整数序列的数量:
  1. 第一项为 n;
  2. 第二项不超过 n;
  3. 从第三项开始,每一项小于前两项的差的绝对值。
  请计算,对于给定的 n,有多少种满足条件的序列。
输入格式
  输入一行包含一个整数 n。
输出格式
  输出一个整数,表示答案。答案可能很大,请输出答案除以10000的余数。
样例输入

4

样例输出

7

本题考查

记忆化深搜,考察点同“历年真题-填字母游戏”

思路

每次深搜首先查询该结果之前是否计算过,若计算过则直接取结果,否则进行递归计算,并将计算结果记录。
定义n为用户输入数字;m为每次函数调用序列中第二个数字;record数组是一个二维数组,用于记录当序列前两个数分别是a,b时序列的可能个数record[a][b]

  1. 循环变量i等于1。
  2. 判断计算当序列前两个数字为ni时的可能序列个数就,调用函数dfs(n,i)进入步骤3。
  3. n-i<=1,根据要求,此种情况只有一种可能序列,直接返回1;若record[n][i]不等于零(此处如果写大于0的话逻辑是没问题的,但java运行起来,判断大于0要比判断不等于0慢,可能会超时),则直接返回record[n][i]的值;若record没有记录该情况,则需要record[n][i]=Σ(record[i][j]),其中0 ≤ j ≤ |n-i|-1,最后将record[n][i]的计算结果记录到record数组中,返回record[n][i]
  4. 最后记录总数的变量count自增步骤2返回值。若循环变量i大于n,则程序结束;否则,循环变量i自增1,进入步骤2。

注意:因为样例中4 1也算作一种可能的序列,所以dfs函数中第三个数j需要从0开始取,当j等于0时,只存在一种可能的情况。
注意:代码第六行的判断条件是递归过程的终点,十分重要

AC代码

import java.util.Scanner;
public class Main {
	static int[][] record = new int[1001][1001];
	static int dfs(int n, int m){  
		int count = 0;
		if(Math.abs(n-m)<=1)	return 1;
		if(record[n][m]!=0)		return record[n][m];
		for (int i = 0; i < Math.abs(n-m); i++)
			if(i==0)	count++;
			else		count+=dfs(m,i);
		record[n][m]=count;
		return count%10000;
	}
	public static void main(String[] args) {
		Scanner scaner = new Scanner(System.in);
		int n = scaner.nextInt();
		scaner.close();
		int count = 0;
		for (int i = 1; i <=n; i++)	count = (count+dfs(n,i))%10000;
		System.out.println(count%10000);
	}
}

你可能感兴趣的:(蓝桥杯,JAVA,java)