更多JAVA版答案移步我的博客:蓝桥杯JAVA版答案汇总
题目
小明想知道,满足以下条件的正整数序列的数量:
1. 第一项为 n;
2. 第二项不超过 n;
3. 从第三项开始,每一项小于前两项的差的绝对值。
请计算,对于给定的 n,有多少种满足条件的序列。
输入格式
输入一行包含一个整数 n。
输出格式
输出一个整数,表示答案。答案可能很大,请输出答案除以10000的余数。
样例输入
4
样例输出
7
本题考查
记忆化深搜,考察点同“历年真题-填字母游戏”
思路
每次深搜首先查询该结果之前是否计算过,若计算过则直接取结果,否则进行递归计算,并将计算结果记录。
定义n
为用户输入数字;m
为每次函数调用序列中第二个数字;record
数组是一个二维数组,用于记录当序列前两个数分别是a
,b
时序列的可能个数record[a][b]
- 循环变量
i
等于1。 - 判断计算当序列前两个数字为
n
,i
时的可能序列个数就,调用函数dfs(n,i)
进入步骤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]
。 - 最后记录总数的变量
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);
}
}