洛谷 P1969 [NOIP2013 提高组] 积木大赛 - 小思维
[NOIP2013 提高组] 积木大赛
题目描述
春春幼儿园举办了一年一度的“积木大赛”。今年比赛的内容是搭建一座宽度为
在搭建开始之前,没有任何积木(可以看成
小 M 是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少。但她不是一个勤于动手的孩子,所以想请你帮忙实现这个策略,并求出最少的操作次数。
输入格式
包含两行,第一行包含一个整数
第二行包含
输出格式
建造所需的最少操作数。
样例 #1
样例输入 #1
5 2 3 4 1 2
样例输出 #1
5
提示
【样例解释】
其中一种可行的最佳方案,依次选择:
【数据范围】
- 对于
的数据,有 ; - 对于
的数据,有 ; - 对于
的数据,有 , 。
思路
- 法一:模拟题意
从前往后依次比较相邻数值大小,如果前面的比后面的大,那么前面的某次操作可以覆盖后面,对答案无贡献;如果前面的比后面小,那么后面的需要额外的操作补足这个高出的部分,高出的部分即为操作的次数
void solve(){ int n, a, ans = 0, last = 0; cin >> n; for(int i = 0; i < n; ++ i){ cin >> a; if(a > last) ans += a - last; last = a; } cout << ans << '\n'; return ; }
- 法二:维护一个递增的单调栈,那么遇到大数先进栈,遇到小数则前面的操作无法为后面产生继续的贡献,出栈并统计答案。记得最后栈内还有元素时最后一个元素一步操作即可
ll n, a[maxm]; void solve(){ cin >> n; stack<int> q; ll ans = 0; for(int i = 0; i < n; ++ i){ cin >> a[i]; int pre = -1; while(q.size() && q.top() > a[i]){ if(pre != -1) ans += pre - q.top(); pre = q.top(); q.pop(); } if(pre != -1) ans += pre - a[i]; if(q.empty() || q.top() < a[i]){ q.push(a[i]); } } int pre = -1; while(q.size()){ if(pre != -1) ans += pre - q.top(); pre = q.top(); q.pop(); } if(pre != 0 && pre != -1) ans += pre; cout << ans << '\n'; return ; }
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17747518.html
分类:
oj - 洛谷
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下