JAVA蓝桥杯 算法训练 VIP试题--ALGO-9摆动序列

本文介绍了一种求解摆动序列数量的算法,通过深度优先搜索(DFS)实现,适用于序列长度不超过20的情况。文章提供了完整的Java代码示例,并提出了一种规律性的解决方案,摆动序列的个数可通过公式(2k-k-1)*2直接计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述
  如果一个序列满足下面的性质,我们就将它称为摆动序列:
  1. 序列中的所有数都是不大于k的正整数;
  2. 序列中至少有两个数。
  3. 序列中的数两两不相等;
  4. 如果第i – 1个数比第i – 2个数大,则第i个数比第i – 2个数小;如果第i – 1个数比第i – 2个数小,则第i个数比第i – 2个数大。
  比如,当k = 3时,有下面几个这样的序列:
  1 2
  1 3
  2 1
  2 1 3
  2 3
  2 3 1
  3 1
  3 2
  一共有8种,给定k,请求出满足上面要求的序列的个数。
输入格式
  输入包含了一个整数k。(k<=20)
输出格式
  输出一个整数,表示满足要求的序列个数。
样例输入
3
样例输出
8

算法分析

1、解此题的关键在于对摆动序列的理解——如果第i – 1个数比第i – 2个数大,则第i个数比第i – 2个数小;如果第i – 1个数比第i – 2个数小,则第i个数比第i – 2个数大。 这句话给定了判断条件,设存放序列的数组为value[]。那么判断该序列是否满足摆动序列的条件即为

(value[n-2]-value[n-3])*(value[n-1]-value[n-3])<0

2、序列中的数两两不相等,建立一个数组isfind[]判断该数字是否遍历过。0为未遍历,1为已经遍历。

3、容易发现当序列长度为2时,原始序列中的任意两个数字都能构成摆动序列,所以当序列长度为2 时,当前结果直接+1。

4、要找出所有摆动序列,那么就是遍历整个1-k中的数,满足条件的就加入到我们用于存放摆动序列的数组value[]中。所以针对此题可以用dfs深度优先搜索来解决。转移状态为n(当前搜索的序列的长度,也可以理解为寻找value[]中的第n个值)。

import java.util.Scanner;

public class 摆动序列{
	static int[] value;//存放序列值
	static int[] isfind;//标记遍历过的点(用1 表示)
	static int sum=0;
	public static int k;
	public static void main(String[] args)
	{
		Scanner sc=new Scanner(System.in);
		k=sc.nextInt();//序列长度[1,k]
		value=new int[k];
		isfind=new int[k+1];
		
		dfs(0);
		System.out.println(sum);
	}
	
	public static void dfs(int n)
	//n:value的索引值(长度为n的序列)
	{
		if(n>1)
		{
			if(n==2)
				sum+=1;
			else if((value[n-2]-value[n-3])*(value[n-1]-value[n-3])<0)
				sum+=1;
			else
				return;
		}
		

		for(int i=1;i<=k;i++)
		{

			if(isfind[i]==0)
			{
				value[n]=i;//找到i未遍历,将其存放在序列的第n个值
				isfind[i]=1;//找到元素就置1
				dfs(n+1);//寻找序列的下一个值
				
				//回溯
				value[n]=0;
				isfind[i]=0;
			}
		}

	}
}

当然,这题也可以通过找规律来完成
摆动序列的个数=(2k-k-1)*2。

蓝桥杯其他的题解代码→→GitHub传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demonslzh6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值