专栏文章

题解:P1044 [NOIP 2003 普及组] 栈

P1044题解参与者 3已保存评论 3

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
3 条
当前快照
1 份
快照标识符
@mipv30z6
此快照首次捕获于
2025/12/03 18:25
3 个月前
此快照最后确认于
2025/12/03 18:25
3 个月前
查看原文

题意

及问你有 nn 个数 11nn,让你求出栈序列的情况总数。

解法

这个题目是经典的数学题,在这里我们硬求肯定是没有办法的,那么我们不妨以递推的视角看一下。 我们可以设一个数组 ff 为在当 nn 为一到十八时,可能的序列总数。 那么此时我们的 f0f_0f1f_1 只有一种情况,而 f2f_2 有两种。 那么我们可以先构造一个栈的结构,我们得到了一个输入序列,接下来就要处理了,下一步求递推公式便是本题的精髓,我们的序列是不是从 11nn 的,我们的 ii 从一开始循环。那么,我们随机挑一个点 kk,以 kk 为中心点我们的序列被劈成了两半,这两段的情况数为 fk1f_{k-1}fikf_{i-k} 这两个,那么根据乘法原理,总可能性为 fk1f_{k-1} ×\times fikf_{i-k} 。最终公式为 fnf_n == f0f_0 ×\times fn1f_{n-1} ++ f1f_1 ×\times fn2f_{n-2} \cdots ++ fn1f_{n-1} ×\times f0f_0。 那么,我们进行枚举,将 11nn 每一个数做这样的处理,将得出的数相乘,就是本题的答案。

代码

CPP
#include <bits/stdc++.h>
using namespace std;
int f[55]={1,1,2};
int main(){
	int n;
	cin >> n;
	for(int i=3;i<=n;i++){
		for(int k=1;k<=i;k++){
			f[i]+=f[k-1]*f[i-k];
		}
	}
	cout << f[n];
	return 0;
}

评论

3 条评论,欢迎与作者交流。

正在加载评论...