两道题都是使用矩形填充满,但是一个是分治,一个是单调栈。
对于区间1~n内,我们有两种涂法
第一种是全部竖着涂,那么需要涂的次数就是宽度r-l+1
第二种是横着涂,先涂满公共最低的高度,然后剩下的高度依次计算。
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX_N = 5010;
int a[MAX_N];
int shu(int l, int r) {
return r - l + 1;
}
int heng(int l, int r) {
int hmin = 0x3f3f3f3f;
for (int i = l; i <= r; ++i) {
hmin = min(hmin, a[i]);
}
for (int i = l; i <= r; ++i) {
a[i] -= hmin;
}
int ans = hmin;
while (l <= r) {
while (l <= r && a[l] == 0) {
l++;
}
int tmp = l;
while (tmp <= r && a[tmp] != 0) {
tmp++;
}
ans += min(heng(l, tmp - 1), shu(l, tmp - 1));
l = tmp;
}
return ans;
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
cout << min(heng(1, n), shu(1, n)) << endl;
return 0;
}
使用单调栈,当出现当前元素小于栈顶元素的时候出栈,当当前元素与栈顶元素相同时,可以减少一次海报覆盖。
n = int(input())
st = []
ans = 0
for i in range(n):
d,w= map(int, input().split())
while st and w <= st[-1]:
if st[-1] == w:
ans += 1
st.pop()
st.append(w)
print(n-ans)