第十一届蓝桥杯模拟赛——摆动序列

问题描述
如果一个序列的奇数项都比前一项大,偶数项都比前一项小,则称为一个摆动序列。即 a2i < a2i-1, a2i+1 > a2i

小明想知道,长度为 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


题解一
DFS(会超时):

#include 
using namespace std;

const int N = 1010;

int a[N];
int n, m, ans;

void dfs(int u)
{
	if(u == m + 1)
	{
		for (int i = 1; i <= m; i ++)
		{
			if(i % 2 == 1 && a[i] <= a[i - 1]) return;
			if(i % 2 == 0 && a[i] >= a[i - 1]) return;
		}
		
		ans ++;
		ans %= 10000;
		return;
	}
	
	for (int i = 1; i <= n; i ++)
	{
		a[u] = i;
		dfs(u + 1);
	}
}

int main()
{
	cin >> m >> n;
	
	dfs(1);
	
	cout << ans << endl;
	return 0;
}

题解二
DFS(依旧会超时):

但由于只枚举合法方案,所以效率高于上面的dfs。

#include 
using namespace std;

int n, m, ans;

void dfs(int u, int pre)
{
	if(u == m)
	{
		ans ++;
		ans %= 10000;
		return;
	}
	
	if(u % 2 == 1)
		for (int i = 1; i < pre; i ++) dfs(u + 1, i);
	else 	
		for (int i = pre + 1; i <= n; i ++) dfs(u + 1, i);
}

int main()
{
	cin >> m >> n;
	
	for (int i = 1; i <= n; i ++) dfs(1, i);
		
	cout << ans << endl;
	return 0;	
}

你可能感兴趣的:(蓝桥杯历届试题)