问题描述
如果一个序列满足下面的性质,我们就将它称为摆动序列:
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传送门
来源:CSDN
作者:Demonslzh
链接:https://blog.csdn.net/Demonslzh/article/details/104185540