P1044 [NOIP2003 普及组] 栈

news2024/11/15 17:39:02

P1044 [NOIP2003 普及组] 栈

方法一:递推dp

思路:

求n的总数,我们可以分解成n在第i(1<=i<=n)位置输出讨论。

我们用a[i][j]表示数i在第j位置输出的情况总数,ans[i][j]表示数i在第1--j位置输出总数和

1,我们发现,a[i][1]=1,理由下面说明

2,我们观察到,在讨论n所在位置的情况时,我们发现,如果位置在n后面的数,一定是按递减输出(容易证明,位置在n后面,说明他们在n输出前都在栈里面,而栈是越小越底层越晚输出),所以,我们变成只需要考虑n在第i个位置前面的1--i-1位置的输出情况

3,考虑n在第i个位置前面的1--i-1位置的输出情况即a[n][i]==ans[n-1][i]

证明如下:

我们在位置i输出n,首先需要把前面n-1个数处理好(要么输出,要么放入栈里面)。如何处理如下图

 4,还注意到,第n个放最后一位,情况数其实就是前面n-1个情况总数

第n个放倒数第二位也是等于前面n-1个情况总数,因为前面n-1个放倒数第二位,与放栈里面等第n个放完再输出是一样的,即a[n][n-1]==ans[n-1][n-1]!=ans[n-1][n-2]

解决完,就可以递推得到答案

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
typedef unsigned long long ull;
typedef pair<long long, long long> pll;
const int INF = 0x3f3f3f3f;
const int N = 20;

int a[N][N], ans[N][N];
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; ++i)//求i个数的情况
		{
			a[i][i] = a[i][i - 1] = ans[i - 1][i - 1];//第i个放最后一位,或者倒数第二位的情况等于前面i-1所有可能情况
			a[i][1] = 1;//第i个数放第一个,后面都是固定的,情况1种,这个放a[i][i] = a[i][i - 1] = ans[i - 1][i - 1];后面是因为前面得到的可能更改a[i][1]
			for (int j = 2; j <= i - 2; ++j)a[i][j] = ans[i - 1][j];//j从i放第二位到倒数第三位处理
			for (int j = 1; j <= i; ++j)ans[i][j] = ans[i][j - 1] + a[i][j];//处理求和
		}
	cout << ans[n][n];
	return 0;
}

方法二,卡特兰数

思路:

进出栈问题实际是经典的卡特兰数问题

我们设函数h[i]表示在i个数的输出情况总数,

我们设k最后一个出栈,发现前面1到k-1的进出栈情况可以看成一个整体,后面k+1到n可以看出一个整体,为什么:

前面k-1个数在k进栈前要先进栈,又因为k最后进栈,那么一旦k进栈,栈里面绝对没有数,k才可以放入最底层,所以前面k-1个数是一个整体,处理k到n个数时,k一直在底层旁观,所以后面是一个整体

那么情况数就是h[k-1]*h[n-k],所以h[n]就是h[j]*h[n-1+j]的求和(0<=j<=n-1,j从0位到倒数第二位)。

显然h[1]=1,我们规定h[0]=1,因为乘法

代码更简洁

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
typedef unsigned long long ull;
typedef pair<long long, long long> pll;
const int INF = 0x3f3f3f3f;
const int N = 20;
int h[N];

int main()
{
	h[0] = h[1] = 1;
	int n;
	cin >> n;
	for (int i = 2; i <= n; ++i)for (int j = 0; j <= i - 1; ++j)h[i] += h[j] * h[i - 1 - j];//求和
	cout << h[n];
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/140802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ROS地图栅格信息

一.地图栅格消息nav_msgs/OccupancyGrid // 栅格地图消息 std_msgs/Header header nav_msgs/MapMetaData info time map_load_time float32 resolution // 分辨率 geometry_msgs/Pose origin // 原点坐标 geometry_msgs/Quaternion orientati…

元数据管理Datahub基于Docker进行部署

目录1. 服务器要求2. 安装Docker3. 安装jq4. 安装python35. 安装docker-compose v1(deprecated&#xff0c;为了兼容性)5.1 安装virtualenv5.2 安装docker-compose6. 安装datahub(在docker-compose-v1-py虚拟环境下)7. 访问Web页面&#xff0c;然后导入测试元数据8. 删除datahu…

数字孪生的概念是什么【深度】

数字孪生技术最早提出是用于航空航天领域&#xff0c;美国 NASA 指出“一个数字孪生&#xff0c;是一种集成化了的多种物理量、多种空间尺度的运载工具或系统的仿真&#xff0c;该仿真使用了当前最为有效的物理模型、传感器数据的更新、飞行的历史等等&#xff0c;来镜像出其对…

C语言C++中与接收、输出字符相关的问题

C语言中&#xff0c;在使用scanf("%c",&data);读取一个字符时&#xff0c;有时会遇到scanf吞回车符的情况。 这里搜到几种常用的解决方法&#xff1a; 1.在scanf()中使用’\n’屏蔽回车符号。 scanf("\n%c",&c);2.在scanf()格式串最前面添加空格&…

【Linux】缓冲区的理解

文章目录什么是缓冲区&#xff1f;为什么要有缓冲区&#xff1f;缓冲区刷新策略请看下面代码&#xff1a;接着上篇【Linux】文件操作|文件描述符|重定向 什么是缓冲区&#xff1f; 我们口中说的缓冲区&#xff0c;一般指的是用户级语言层面给我们提供的缓冲区。本质就是一段…

nRF24L01芯片(模块)介绍

nRF24L01芯片&#xff08;模块&#xff09;简介nRF24L01是由NORDIC生产的工作在2.4GHz~2.5GHz的ISM 频段的单片无线收发器芯片。无线收发器包括&#xff1a;频率发生器、增强型“SchockBurst”模式控制器、功率放大器、晶体振荡器、调制器和解调器。输出功率频道选择和协议的设…

使用 K8S 部署 RSS 全套自托管解决方案- RssHub + Tiny Tiny Rss

前言 什么是 RSS? RSS 是一种描述和同步网站内容的格式&#xff0c;是使用最广泛的 XML 应用。RSS 搭建了信息迅速传播的一个技术平台&#xff0c;使得每个人都成为潜在的信息提供者。发布一个 RSS 文件后&#xff0c;这个 RSS Feed 中包含的信息就能直接被其他站点调用&…

【MySQL】SQL查询语句在MySQL中的执行过程

文章目录1.MYSQL基础架构2.连接器3.查询缓存4.解析SQL5.执行SQL5.1 预处理器5.2 优化器5.3 执行器6.总结1.MYSQL基础架构 连接器&#xff1a;建立连接、管理链接、校验用户身份查询缓存&#xff1a; 查询语句如果命中查询缓存则直接返回&#xff0c;否则继续往下执行。&#xf…

基于Java+SpringBoot+vue+element疫情物资捐赠分配系统设计和实现

基于JavaSpringBootvueelement疫情物资捐赠分配系统设计和实现 &#x1f345; 作者主页 超级帅帅吴 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 文章目录基于JavaSpringBootvueelement疫情物资捐赠分配…

不能你说对不起,别人就一定要说没关系——与九迁沟通他的冲动和错误

今天的事情是最近三天九迁与他奶奶之间发生的事情。先说前面在谈事件&#xff0c;这个事情的发生&#xff0c;首先说明我母亲的身体还可以&#xff0c;没有被感染&#xff0c;因为还能和孩子生气&#xff0c;说明熊胆粉确实是在起作用&#xff0c;关于熊胆粉的文章请看&#xf…

FGH40N60SMD 600V 80A 349W 逆变器高频IGBT单管

FGH40N60SMD 600V 80A 349W 逆变器高频IGBT单管 &#xff0c;为光伏逆变器、UPS、焊机、通讯、ESS 和 PFC 等低导通和开关损耗至关重要的应用提供最佳性能。IGBT单管系列&#xff1a;FGH40N60SMDFGH60N60SMDFGH75T65SHD-F155 NGTB40N120FL2WG特性&#xff1a;1.最大结温 T[siz…

C++:二叉树题进阶(三种非递归遍历、二叉搜索树OJ题)

lc 606 根据二叉树创建字符串 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 “()” 表示&#xff0c;转化后需要省略所有不影响字符串与原始…

C++4:C++中的动态内存管理

目录 C内存管理方式 new/delete操作内置类型&#xff1a; new/delete操作自定义类型&#xff1a; new和delete的底层实现&#xff1a; operator new与operator delete函数 定位new 内存泄漏 动态内存管理&#xff0c;早些我们接触C语言的时候就已经在很熟练的游玩在堆上开…

QGIS加载谷歌地图(google map)方法

目录第一步第二步将Google提供的网络地图&#xff0c;包括地图和卫星影像等&#xff0c;作为图层加载到QGIS中&#xff0c;有时可辅助地学分析。QGIS已经提供了OpenStreetMap&#xff0c;在 “XYZ Tiles” 里面加载即可。 谷歌街道地图&#xff1a;http://mt2.google.com/vt/ly…

缓冲区的深刻理解

代码&&现象 先来看一份代码 #include <stdio.h> #include <string.h> #include <unistd.h> int main() {//C Libraryprintf("hello printf\n");fprintf(stdout, "hello fprintf\n");const char *s1 "hello fwrite\n&quo…

微信公众号开发以及测试公众号菜单配置

微信公众号开发测试号申请测试号配置公众号菜单配置1、获取access_token2、新增自定义菜单微信扫描关注公众号微信公众平台测试号申请 1、测试号申请 开发的时候需要一个个人的公众号调试&#xff0c;所以使用微信测试号进行。 1、微信测试号申请地址: https://mp.weixin.qq.c…

用于野外精确人体姿态估计的自适应多视图融合

用于野外精确人体姿态估计的自适应多视图融合 Abstract AdaFuse&#xff1a;一种自适应的多视图融合方法&#xff0c;利用可见视图中的特征增强被遮挡视图中的特征核心&#xff1a;确定两个视图之间的点-点对应关系 通过研究热图表示的稀疏性 我们还学习了一个自适应的融合…

ArcGIS基础实验操作100例--实验48按分区划分矢量图层

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验48 按分区划分矢量图层 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;…

属于 PingCAP 用户和开发者的 2022 年度记忆

2022 年&#xff0c;我们一起穿越了许多荆棘时刻&#xff0c;面对着前所未有的不确定性。在这些挑战面前&#xff0c;我们发现技术和开发者扮演了重要角色。 技术为我们提供了穿越周期的桥梁&#xff0c;开发者帮助我们更好地应对挑战&#xff0c;解决问题并赋予这个世界更多创…

Qt——项目:翻转金币游戏

目录 一.示例演示 二.制作思路 &#xff08;一&#xff09;.准备资源及总体框架 &#xff08;二&#xff09;.开始窗口 &#xff08;三&#xff09;.选择关卡窗口 &#xff08;四&#xff09;.游戏窗口 &#xff08;五&#xff09;.优化 三.实现代码 &#xff08;一&a…