摆动序列#
问题描述
如果一个序列的奇数项都比前一项大,偶数项都比前一项小,则称为一个摆动序列。即 a[2i]<a[2i-1], a[2i+1]>a[2i]。
小明想知道,长度为 m,每个数都是 1 到 n 之间的正整数的摆动序列一共有多少个。
输入格式
输入一行包含两个整数 m,n。
输出格式
输出一个整数,表示答案。答案可能很大,请输出答案除以10000的余数。
样例输入
3 4
样例输出
14
样例说明
以下是符合要求的摆动序列:
2 1 2
2 1 3
2 1 4
3 1 2
3 1 3
3 1 4
3 2 3
3 2 4
4 1 2
4 1 3
4 1 4
4 2 3
4 2 4
4 3 4
评测用例规模与约定
对于 20% 的评测用例,1 <= n, m <= 5;
对于 50% 的评测用例,1 <= n, m <= 10;
对于 80% 的评测用例,1 <= n, m <= 100;
对于所有评测用例,1 <= n, m <= 1000。
我的傻逼暴力解法:
package 往年例题;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @author diao 2022/3/20
*/
//a[2i]<a[2i-1],a[2i+1]>a[2i]
public class 摆动序列 {
static int count=0;
static ArrayList<String> tempList=new ArrayList<String>();
public static void main(String[] args) {
/* //1.输入n:1-n之间的摆动序列有多少,摆动序列长度为m*/
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n=sc.nextInt();
sc.nextLine();
}
/* //2.首先要根据输入的n全排列一下,*/
public static int[] list(int n) {
//2.1先把数添加到数组中
int[] arr = new int[n];
for (int i = 1; i <= n; i++) {
arr[i-1]=i;
i++;
}
return arr;
}
/*//2.2将数组中的数字组合排列,组合后的内容放到新的数组中*/
public static List dfs(int[]arr,int index){
//1.结束条件,当index到末尾时结束
if(index==arr.length){
String s="";
for(int i=0;i<arr.length;i++){
int i1 = arr[i];
//1.2全排列中的一个数(1-n)
s+=arr[i];
}
//1.3将全排列好的一个字符串放入集合中
tempList.add(s);
}
//2.递归思路
for(int i=index;i<arr.length;i++){
{
int temp=arr[index];
arr[index]=arr[i];
arr[i]=temp;
}
//2.2index+1,到下一个位置上
dfs(arr,index+1);
{//回溯
int temp=arr[index];
arr[index]=arr[i];
arr[i]=temp;
}
}
return tempList;
}
//因为集合中内容是字符串,需要转为数组
public static int[] parse(List list){
int[] arr = new int[list.size()];
for(int i=0;i<list.size();i++){
arr[i]=Integer.parseInt((String) list.get(i));
}
return arr;
}
//获得数组中的整数长度
public static int getLength(int a){
while(a!=0){
a/=10;
count++;
}
return count;
}
//将一个数组1中的整数(这个数组中是全排列的数)拆成装满组一个个零散的数
public static int[] getNewArr(int a){
int length = getLength(a);
ArrayList<Integer> list = new ArrayList<>();
int[] newArr = new int[length];
while(a!=0){
int i = a % 10;
a/=10;
list.add(i);
}
for(int i=0;i<list.size();i++){
newArr[i]=list.get(i);
}
return newArr;
}
/*
//4.temp数组由上面方法得到集合再转化,里面有所有的全排列,m意思是一个排列的前m个数
*/
public static void find(int m,int n,int[]temp){
String s="";
//1.里面都是全排列整数,
for(int i=0;i<temp.length;i++){
//2.全排列的每个数转为一个新数组,里面是一个个的数字,方便判断是否摆动
for(int j=1;j<getLength(temp[i]);j++) {
int[] arr = getNewArr(temp[i]);
//3.满足摆动序列思路
if (arr[i] < arr[j - 1] && arr[j + 1] > arr[j]) {
String str = s + arr[j - 1] + arr[j] + arr[j + 1];
System.out.println(str);
}
}
}
}
}
写了一个小时,mad
看看人家的
public class _008 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] ch =new int[m+2][n+2];
for (int i =1 ; i <= n ;i++){
ch[1][i]=n-i+1;
}
for(int i=2;i<=m;i++){
if((i&1)==1){
for(int j=n;j>=1;j--)
ch[i][j]=(ch[i-1][j-1]+ch[i][j+1])%1000;
}else{
for(int j=1;j<=n;j++)
ch[i][j]=(ch[i-1][j+1]+ch[i][j-1])%1000;
}
}
int result= (m&1)==1? ch[m][1]:ch[m][n];
System.out.println(result);
}
}