蓝桥 摆动序列 (dp)

问题描述
如果一个序列的奇数项都比前一项大,偶数项都比前一项小,则称为一个摆动序列。即 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。

比赛的时候用的暴力搜索,应该是得不了多少分。
看了好几个题解才看明白动态规划怎么做,这里记录一下,都在注释里了。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

//i表示第几位

//i为奇数-->dp[i][j]:第i位是大于等于j的个数
//dp[i][j]=dp[i-1][j-1]+dp[i][j+1]

//i为偶数-->dp[i][j]:第i位是小于等于j的个数
//dp[i][j]=dp[i-1][j+1]+dp[i][j-1]
int dp[1005][1005];
int n, m;
int main(){
	cin>>m>>n;
	for (int j=1; j<=n; j++){
		dp[1][j]=n-j+1;
	}
	for (int i=2; i<=m; i++){
		if (i&1){
			for (int j=n; j>=1; j--){
				dp[i][j]=(dp[i-1][j-1]+dp[i][j+1])%10000;
			}
		}else{
			for (int j=1; j<=n; j++){
				dp[i][j]=(dp[i-1][j+1]+dp[i][j-1])%10000;
			}
		}
	}
	int res = m&1? dp[m][1] : dp[m][n];
	cout<<res;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

H4ppyD0g

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值