蓝桥杯4月校内模拟题第八题--摆动序列

**

蓝桥杯4月校内模拟题第八题

**
摆动序列
如果一个序列的奇数项都比前一项大,偶数项都比前一项小,则称为一个摆动序列。
即 a2ia2i
小明想知道,长度为 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

题解:
由a2ia2i可知我们只需要求偶数项的前一个数和后一个数与偶数项比较,两个数都比偶数大就为摆动序列(左右两个数可重复)。
刚开始的时候我第一时间想到暴力破解,采用dfs不断递归找到比偶数项大的数求出答案,但想到dfs要开辟大量的空间进行计算,优化后改为记忆型dfs,但数据很大时依旧会超时。
于是我就想能不能找到其中的规律,减少运算的时间。
采用例子输入3,4。3个数,范围1-4,当偶数项为1时,比偶数项大的数有2,3,4,当偶数项为2时,比偶数项大的数有3,4,当偶数项为3时,比偶数项大的数有4。

你会发现一个规律:偶数项的值加上比偶数项大的数的个数恰好等于n。
比偶数项大的数的个数=n-偶数项的值。

因为偶数项左右两边可以重复,比偶数项大的数的个数的平方就等于偶数项的值的摆动数列个数。即偶数项的值为1时,它的摆动数列个数为(n-1)^2
所以递推出一个偶数项摆动数列个数和为1+…+(n-1)^2

你可能会问1是怎么出来的,因为偶数项要想有摆动数列,偶数项的值必须 (n-(n-1))^2=1

由于偶数项可能不止一个,但偶数项的摆动数列个数是相同的
所以偶数项个数*偶数项的摆动数列个数%10000得出最后结果

代码如下:

#include
#include
using namespace std;
int main(){
	int m,n,i,count=0,sum=0;
	cin>>m>>n;
	//m个数,范围1-n 
	//举例子 3个数,范围1-5 
	//n-1*n-1 16 比n大的数互相组合 
	//n-2*n-2 9
	//n-3*n-3 4
	//n-4*n-4 1	
	for(i=2;i<m;i+=2){
		count++;//求出偶数项的个数 
		if(count>10000)
		count=count%10000;//防止偶数项个数超过上限
	}
	for(i=1;i<n;i++){
		sum+=pow(i,2);	
		if(sum>10000)
		sum=sum%10000;//防止摆动序列和超过上限
//	1+4+9+16 一个偶数的摆动序列为1+...+(n-1)^2
	}
	cout<<count*sum%10000<<endl;//两者相乘%10000得到结果 
	return 0;
}

第一次写博客,如果写的不好请大家见谅。

你可能感兴趣的:(蓝桥杯4月校内模拟题第八题--摆动序列)