bzoj1345[Baltic2007]序列问题Sequence*

bzoj1345[Baltic2007]序列问题Sequence

题意:

n个数,合并ai和ai+1可以得到max(ai,ai+1),代价为max(ai,ai+1)。问合并n-1次最小代价为多少。n≤1000000。

题解:

(来自题解,因为我不知道为什么这样做)维护一个单调递减栈。对于每个加入的元素,若加入后不满足单调性质,则让其与栈顶-1的元素比较:如果加入的数大,则合并栈顶和栈顶-1的数(把栈顶去掉),费用为栈顶-1;否则合并当前与栈顶的数(把栈顶去掉),费用为当前数。重复上述操作,直到满足单调性后入栈。最后从顶向下合并。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define maxn 1000010
 6 #define INF 0x3fffffff
 7 using namespace std;
 8 
 9 inline int read(){
10     char ch=getchar(); int f=1,x=0;
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
13     return f*x;
14 }
15 int st[maxn]; int n,top; long long ans;
16 int main(){
17     n=read(); st[0]=INF;
18     inc(i,1,n){
19         int x=read();
20         while(top&&x>=st[top]){
21             if(x>=st[top-1])ans+=st[top-1],top--;else ans+=x,top--;
22         }
23         st[++top]=x;
24     }
25     while(top>1)ans+=st[--top]; printf("%lld",ans); return 0;
26 }

20160927

原文地址:https://www.cnblogs.com/YuanZiming/p/5966641.html