2019牛客暑期多校训练营(第二场场)_H题Second Large Rectangle
2019-08-07 03:23
375 查看
题目链接: https://ac.nowcoder.com/acm/contest/882/H
思路:(转载自: https://www.cnblogs.com/pisceskkk/p/11229105.html)
首先考虑求最大矩形:
不妨考虑以第i行为底边的矩形,那么就转化成直方图求最大矩形面积。
如图
当我们遇到第三列时,第二列的高度已经不能拓展,因此将其清算掉,同时将第三列高度加入栈中。
即使用单调栈维护所有高度中最靠右且小于当前高度的位置(注意单调)。
进而考虑求第二大,情况有二,所有完整的尽量大的矩形中第二大,或者尽量大的矩形去掉一行或者一列。由于我们按行以此求解,只需要额外考虑去掉一列的情况就OK。
单调栈的一道经典题
力扣: 柱状图中最大的矩形: https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
同样也是用单调栈去维护一个非递减序列
代码
#include <bits/stdc++.h> using namespace std; int mp[1005][1005]; int sum[1005]; int main() { ios::sync_with_stdio(false); int n, m; while(cin >> n >> m){ int maxn = 0, minn = 0; string s; for(int i = 1; i <= n; i++){ cin >> s; sum[i] = 0; for(int j = 1; j <= m; j++){ mp[i][j] = (s[j - 1] - '0'); } mp[i][m + 1] = 0; } for(int i = 1; i <= n; i++){ stack<int> st; int ans; st.push(0); // 设置矩形的坐界限 for(int j = 1; j <= m + 1; j++){ sum[j] = (mp[i][j] == 1 ? sum[j] + 1 : 0); while(st.size() > 1 && sum[j] <= sum[st.top()]){ int k = st.top(); st.pop(); ans = sum[k] * ((j - 1) - st.top()); // 宽 * 底面长 if(ans > maxn){ minn = maxn; maxn = ans; ans -= sum[k]; //因为我们求的第二大 所以我们要尝试去掉一行或者一列再去与第二大做比较, 因为我们是按行来求解的所以我们只要尝试去掉一列即可, 即宽 * (底面长 - 1) if(ans > minn){ minn = ans; } } else if(ans > minn){ minn = ans; } } st.push(j); } } cout << minn << endl; } return 0; }
相关文章推荐
- 2019牛客暑期多校训练营(第二场) - H - Second Large Rectangle - dp
- 2019牛客暑期多校训练营(第二场)
- 暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第二场)
- 2019牛客暑期多校训练营(第四场)A
- 2019牛客暑期多校训练营(第六场)J(枚举)
- 2019牛客暑期多校训练营(第一场)
- 2019牛客暑期多校训练营(第三场)
- 2019牛客暑期多校训练营(第二场)
- 2019牛客暑期多校训练营(第一场),A题(笛卡尔树)
- 2019牛客暑期多校训练营 第二场
- 2019牛客暑期多校训练营 第五场
- 2019牛客暑期多校训练营(第三场)
- 2019牛客暑期多校训练营(第四场)I string —— 后缀自动机+回文自动机
- 2019牛客暑期多校训练营(第一场)J:Fraction Comparision
- 2019牛客暑期多校训练营(第七场)
- 2019牛客暑期多校训练营(第一场) - A - Equivalent Prefixes - 单调栈
- 2019牛客暑期多校训练营(第二场) - F - Partition problem - 枚举
- 2019牛客暑期多校训练营(第七场)A(暴力)
- 2019牛客暑期多校训练营 第四场
- 2019牛客暑期多校训练营(第七场)H(数位DP)