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

柔情痞子 提交于 2020-02-06 00:01:50

问题描述
  如果一个序列满足下面的性质,我们就将它称为摆动序列:
  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传送门

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!