首页 > 其他分享 >P1044 [NOIP2003 普及组] 栈

P1044 [NOIP2003 普及组] 栈

时间:2022-12-25 17:32:04浏览次数:42  
标签:输出 普及 出栈 拿出 NOIP2003 int static P1044 序列

题目背景

栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。

栈有两种最重要的操作,即 pop(从栈顶弹出一个元素)和 push(将一个元素进栈)。

栈的重要性不言自明,任何一门数据结构的课程都会介绍栈。宁宁同学在复习栈的基本概念时,想到了一个书上没有讲过的问题,而他自己无法给出答案,所以需要你的帮忙。

题目描述

P1044 [NOIP2003 普及组] 栈_出栈

宁宁考虑的是这样一个问题:一个操作数序列,P1044 [NOIP2003 普及组] 栈_操作数_02(图示为 1 到 3 的情况),栈 A 的深度大于 P1044 [NOIP2003 普及组] 栈_出栈_03

现在可以进行两种操作,

  1. 将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的 push 操作)
  2. 将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的 pop 操作)

使用这两种操作,由一个操作数序列就可以得到一系列的输出序列,下图所示为由 ​​1 2 3​​ 生成序列 ​​2 3 1​​ 的过程。

P1044 [NOIP2003 普及组] 栈_操作数_04

(原始状态如上图所示)

你的程序将对给定的 P1044 [NOIP2003 普及组] 栈_出栈_03,计算并输出由操作数序列 P1044 [NOIP2003 普及组] 栈_出栈_06 经过操作可能得到的输出序列的总数。

输入格式

输入文件只含一个整数 P1044 [NOIP2003 普及组] 栈_出栈_03P1044 [NOIP2003 普及组] 栈_操作数_08)。

输出格式

输出文件只有一行,即可能输出序列的总数目。

输入输出样例

输入 #1复制

3

输出 #1复制

5

说明/提示

【题目来源】

NOIP 2003 普及组第三题


思路分析:

题目要我们求从管倒出来的顺序有多少个,即出栈顺序有多少个,假设三个球123加入栈中,出栈方式可以是123(放进去一个球接着拿出来)、321(三个球全放进去再挨个拿出来)、231(当进去两个球再拿出一个再放第三个再依次拿出来)...。但是由于栈是先进后出的,有些序列比如312就不存在,因为要想先拿出3,1必定在2的后面拿出。

我们假设对于n个元素我们有a[n]个出栈方式,假如第k个元素是最后拿出的,则比k早拿出的元素有k - 1个,比k晚拿出的元素有n - k个,则一共有a[k - 1] * a[n - k]种出栈方式,因为对于早拿出的k - 1个数,其中又存在一个k1是最后那个拿出的,则就有k1 - 1个更早拿出的数,k - 1 - k1个更晚拿出的数,以此类推。我们可以得到,当k取不同的值时,产生的出栈顺序是相互独立的,各自不会产生影响或出栈顺序重复,因为k是不同的。

所以我们将所有k的取值产生的出栈结果加起来,就是我们要求的所有出栈顺序。递推关系式可以写为:a[n] = a[0] * a[n - 1] + a[1] * a[n - 2] + ... + a[n - 1] * a[0]。(表示k取0~n-1时,各自产生的出栈顺序之和)。

另外,对于递推式,要想让其不断执行下去,必须要有一个或多个初始值。本题的初始值是a[0] = 1,因为k==1,表示第1个数最后出栈,比他早出栈的数没有,比他后出栈的有n - 1个数,出栈方式为a[n - 1],总共出栈方式是a[0] * a[n - 1],所以a[0] = 1,而不是a[0] = 0,如果a[0] = 0,则总结果变成0,错误;另一个初始值是a[1] = 1,表示第2个数最后出栈,比他早出栈的数只有第一个数,其出栈方式就一种,所以a[1] = 1。


代码如下:

import java.util.Scanner;

public class 栈 {
static final int N = 20;
static int[] a = new int[N];
static int n;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
a[0] = a[1] = 1;
for(int i = 2; i <= n; i++)
for(int j = 0; j < i; j++){
// 递推式:a[i] = a[0] * a[i - 1] + a[1] * a[i - 2] + ... + a[i - 1] * a[0]
a[i] += a[j] * a[i - j - 1];
}
System.out.println(a[n]);
}
}




标签:输出,普及,出栈,拿出,NOIP2003,int,static,P1044,序列
From: https://blog.51cto.com/u_15065134/5968226

相关文章

  • [NOIP2009 普及组] 多项式输出
    [NOIP2009普及组]多项式输出题目描述一元$n$次多项式可用如下的表达式表示:$$f(x)=a_nxn+a_{n-1}x{n-1}+\cdots+a_1x+a_0,a_n\ne0$$其中,$a_ix^i$称为$i$次项,$a......
  • GO语言基础 为什么我要学习Golang以及GO语言入门普及
    作为网络安全初学者,会遇到采用Go语言开发的恶意样本。因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识;另一方面是分享与读者,希望大家一起进......
  • CodeStar2022年秋第10周周赛普及进阶组
    T1:子序列相似度本题难度中等,做法和编辑距离类似,用dp[i][j]表示\(s\)的长为\(i\)的前缀和\(t\)的长为\(j\)的前缀的最大相似度初值:\(dp[0][0]=0\)转移:\(d......
  • CodeStar2022年秋第9周周赛普及奠基组
    T1:k的幂分拆本题难度中等,完全背包模板题,以\(k\)的幂作为物品大小记dp[i][j]表示使用若干个\(k^0\simk^i\),相加恰好为\(j\)的方案数转移:\(dp[i][j]=dp[i-......
  • CodeStar2022年秋第9周周赛普及奠基组
    T1:矩阵涂色本题难度简单,考察二维数组的基本使用。矩阵最终状态中,如果某一行全是红色,说明最后一次操作是R操作,如果某一列全是蓝色,说明最后一次操作一定是B操作代......
  • CodeStar2022年春第十一周周赛普及奠基组
    T1:牛奶供应本题难度简单,主要考察贪心算法。第\(i\)天的牛奶成本价为\(\min(c_i,minp+s)\),其中\(minp\)为前\(i-1\)天中牛奶的最低成本价代码实现#include<bit......
  • P2671 [NOIP2015 普及组] 求和
    [NOIP2015普及组]求和题目背景NOIP2015普及组T3题目描述一条狭长的纸带被均匀划分出了\(n\)个格子,格子编号从\(1\)到\(n\)。每个格子上都染了一种颜色\(color_i\)......
  • CodeStar第八周周赛普及进阶组
    T1:垃圾游戏3本题难度中等,一道稍有变化的01背包题。一般的01背包是考虑每个物品取和不取,本题是考虑每个物品带走(相当于取)还是分解(相当于不取),如果分解,也会贡献相应价值记d......
  • p1015 [NOIP1999 普及组] 回文数
    [NOIP1999普及组]回文数题目描述若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。例如:给定一个十进制数\(56\),将\(56\)加\(65\)(即把\(5......
  • About [NOIP2003 普及组] 数字游戏
    题目描述丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前有......