cychester

BZOJ 1345[BOI]序列问题 - 贪心 + 单调栈

题解

真的没有想到是单调栈啊。 回想起被单调栈支配的恐惧

最优情况一定是小的数去合并 尽量多的数,所以可以维护一个递减的单调栈。

如果加入的数比栈首小, 就直接推入栈。

如果加入的数大于等于栈首, 必须要合并栈首,因为栈首两边都是大的数, 要选择小的那个进行合并, 需要进行$st[top - 1] 与 x$判断大小。

最后留下来的递减数列逐个合并就可以了

代码

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define rd read()
 5 using namespace std;
 6 
 7 const int N = 1e6 + 1e5;
 8 
 9 int st[N], tp, n;
10 long long ans;
11 
12 int read() {
13     int X = 0, p = 1; char c = getchar();
14     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
15     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
16     return X * p;
17 }
18 
19 int main()
20 {
21     n = rd;
22     for(int i = 1; i <= n; ++i) {
23         int x = rd;
24         while(tp && st[tp] <= x) {
25             if(tp > 1 && st[tp - 1] < x) ans += st[tp - 1];
26             else ans += x;
27             tp--;
28         }
29         st[++tp] = x;
30     }
31     while(tp > 1) {
32         ans += st[--tp];
33     }
34     printf("%lld\n", ans);
35 }
View Code

 

posted on 2018-08-20 15:32  cychester  阅读(219)  评论(0编辑  收藏  举报

导航