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