题目
题意
给一串数字,如果左边数字大于右边,右边数字可以被消去,在被左边数字消去的同时,这个数字也可以消去自己右边的数字(如果满足条件)。所以我只需要找出所有数字被消去轮数的最大值即可,这个要求可以用一个单调栈来完成。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int f[100005], n, t, cnt;
stack<int> v;
cin>>n;
memset(f, 0, sizeof(f));
for (int i=0; i<n; i++) {
cin>>t;
cnt = 0;
if (v.size() == 0) {
v.push(t);
continue;
}
while (v.top() < t) {
cnt = max(cnt, f[v.top()]);
v.pop();
if (v.size() == 0) break;
}
if (v.size() == 0) {
v.push(t);
continue;
}
f[t] = cnt + 1;
v.push(t);
}
int ans = 0;
for (int i=0; i<n; i++)
ans = max(ans, f[i]);
printf("%d\n", ans);
return 0;
}
思路
先找到第一个可以吃别的数的数,将它存入栈中,在找下一个数,如果这个数比栈顶元素小,入栈,否则将栈顶元素弹出,循环直到栈顶大于该数或是栈为空,该数存在轮数为被它弹出元素的轮数的最大值+1。
总结
本题2000分,主要是要想到利用栈的n的复杂度模拟,才不会超时。思路很独特,不好想(对于我来说)。
本题有更好的代码写法,但是因为主要是思路重要,代码写得如何只要不影响复杂度就不是大问题,就没有改。
这道题想了很久,主要是因为栈的用法很灵活,一下没想到,看了看别人的思路再自己尝试写才写出来。