CodeForces - 1313C2 Skyscrapers (hard version)(单调栈+dp)
题目链接:点击这里
题目大意:
给出一个长度为 nnn 的序列 aia_iai ,现求一个序列 bib_ibi ,使得其满足 bi≤aib_i \le a_ibi≤ai 且 bib_ibi 先增后减,现在求 ∑i=1nai−∑i=1nbi\sum_{i=1}^na_i-\sum_{i=1}^nb_i∑i=1nai−∑i=1nbi 最小的序列 bbb ,若有多种方案输出任意一种即可
题目分析:
不难想到一个 O(n2)O(n^2)O(n2) 的暴力,枚举点 iii 为最高点,然后 O(n)O(n)O(n) 更新序列,选取差值最小情况即可的即可
考虑优化,分别用 dp1i,dp2idp1_i,dp2_idp1i,dp2i 维护从前到后到 iii 位置的元素和的最大值,从后到前到 iii 的元素的最大值,那么答案就是 max(dp1i+dp2i−ai)max(dp1_i+dp2_i-a_i)max(dp1i+dp2i−ai) (减去 aia_iai 是因为 aia_iai 被重复计算贡献了)
接下来考虑状态转移,以 dp1dp1dp1 为例( dp2dp2dp2 同理):dpi=dppos+(i−pos)aidp_i=dp_{pos}+(i-pos)a_idpi=dppos+(i−pos)ai ,其中 pospospos 为从 iii 往前第一个满足 apos<aia_{pos}<a_iapos<ai 的 pospospos 。这个 pospospos 不难想到可以用一个单调栈来维护,这样就可以 O(n)O(n)O(n) 预处理出两个 dpdpdp 数组了。然后 O(n)O(n)O(n) 枚举最大值位置即可
具体细节见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<stack>
#define ll long long
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
#define int ll
using namespace std;
int read()
{int res = 0,flag = 1;char ch = getchar();while(ch<'0' || ch>'9'){if(ch == '-') flag = -1;ch = getchar();}while(ch>='0' && ch<='9'){res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';ch = getchar();}return res*flag;
}
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,maxx,a[maxn],dp1[maxn],dp2[maxn],ans[maxn];
bool flag;
stack<int>st;
signed main()
{n = read();for(int i = 1;i <= n;i++) a[i] = read(),maxx = max(maxx,a[i]);a[0] = a[n+1] = -inf;st.push(0);for(int i = 1;i <= n;i++){while(!st.empty() && a[st.top()] >= a[i]) st.pop();int pos = st.top();dp1[i] = dp1[pos]+(i-pos)*a[i];st.push(i);}while(!st.empty()) st.pop();st.push(n+1);for(int i = n;i;i--){while(!st.empty() && a[st.top()] >= a[i]) st.pop();int pos = st.top();dp2[i] = dp2[pos]+(pos-i)*a[i];st.push(i);}int maxx = 0,pos = 0;for(int i = 1;i <= n;i++){if(maxx < dp1[i]+dp2[i]-a[i]){maxx = dp1[i]+dp2[i]-a[i];pos = i;}}ans[pos] = a[pos];for(int i = pos-1;i;i--) ans[i] = min(ans[i+1],a[i]);for(int i = pos+1;i <= n;i++) ans[i] = min(ans[i-1],a[i]);for(int i = 1;i <= n;i++) printf("%lld%c",ans[i],i==n ? '\n' : ' ');return 0;
}
CodeForces - 1313C2 Skyscrapers (hard version)(单调栈+dp)相关推荐
- CodeForces - 1313C2 Skyscrapers (hard version)(单调栈+dp/分治)
题目链接:点击查看 题目大意:给出 n 块连续的空地可以建造摩天大楼,政府有规定,每块地最高只能建 a[ i ] 的高度,同时每栋大楼需要满足一个规则,即每栋大楼的两侧不允许同时存在比自己高的大楼,输 ...
- CodeForces - 1407D Discrete Centrifugal Jumps(单调栈+dp)
题目链接:点击查看 题目大意:给出 n 个大楼的高度记为 h,现在需要从第一个大楼到达第 n 个大楼,问最小步数是多少,只有满足以下条件时才能从 i 移动到 j ,设 i < j: 题目分析:无 ...
- [codeforces 1313C1] Skyscrapers (easy version) 问的是谷,答的是峰
Codeforces Round #622 (Div. 2) 比赛人数5752 [codeforces 1313C1] Skyscrapers (easy version) 问的是谷,答的是峰 ...
- CodeForces - 548D Mike and Feet(单调栈)
题目链接:点击查看 题目大意:给出一个长度为 n 的数列,现在规定对于任意长度区间为 len 的答案为,所有长度为 len 的区间内的最小值的最大值,题目要求我们输出len为 1 ~ n 时的答案 题 ...
- [ZJOI2007] 棋盘制作(单调栈 / DP悬线法)
problem 洛谷链接 solution1-单调栈 很容易想到,预处理出每个点向上最大能延伸的长度,然后对每个点求一个矩阵面积. 然后思考优化,不难想到每次对一行进行求解. 每一行的所有列一起构成了 ...
- 【Codeforces 631C 】Report(单调栈,思维模拟)
题干: Each month Blake gets the report containing main economic indicators of the company "Blake ...
- P3400 仓鼠窝 (单调栈 dp
添加链接描述 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e3+9; l ...
- P3400 仓鼠窝 (单调栈 dp O(n*m
添加链接描述 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e3+9; l ...
- Skyscrapers (hard version) CodeForces - 1313C2(单调栈)
This is a harder version of the problem. In this version n≤500000 The outskirts of the capital are b ...
- CodeForces - 1484E Skyline Photo(dp+单调栈)
题目链接:点击查看 题目大意:给出 nnn 个建筑,每个建筑有一个高度和一个美丽值,现在要求划分为数个连续的区间,使得所有区间的贡献之和最大,其中每个区间的贡献值为,区间中高度最低的建筑物的美丽值 题 ...
最新文章
- 【邓侃】哈佛大学机器翻译开源项目 OpenNMT的工作原理
- 7.Redis常用命令:ZSet
- wireshark应用--wireshark原来那么简单
- Revit API创建标高,单位转换
- 前端学习(2513):组件css作用域
- soap rest_这是我对REST的后续工作,是新的SOAP:让我们谈谈原始REST
- 设计作品展示类网站,设计提升调性必不可少
- 几个对字符串进行操作的函数
- OpenCV-高斯低通高通滤波器(C++)
- 【视频】文本挖掘:主题模型(LDA)及R语言实现分析游记数据
- 好的串行代码与好的并行代码的区别(Zz)
- 一篇文章教你如何刷Letcode进大厂
- 推荐测温软件SpeedFan 4.32
- 读Zepto源码之Deferred模块
- 兵法三十六计第二计-围魏救赵。
- 全角和半角的区别及使用方式
- halcon算法库中各坐标系,位姿的解释及原理
- iOS开发 - ANPs推送通知
- 日文假名输入与键盘对应
- MT2007-快速判断一个数能否被整除
热门文章
- Adobe Photoshop CS5 12.0 Extend 绿色免安装版
- 通州区机器人比赛活动总结_机器人大赛总结报告
- 信安小组 第三周 总结
- MC2D v0.0.6 Source Code
- Linux文件其他操作
- 项目经理一定要知道的PMP项目管理八大会议流程-(PMBOK高频考点)
- QQ认证空间已升级QQ公众空间,申请地址是?
- 求学信计算机专业英语,英语求学信模板
- Pivotal任命Lionel Lim为Pivotal公司副总裁兼亚太区常务董事
- 驱动启动时遇到:打开服务失败(错误码=6):句柄无效 解决方案