zoukankan      html  css  js  c++  java
  • BZOJ_1345_[Baltic2007]序列问题Sequence_单调栈

    BZOJ_1345_[Baltic2007]序列问题Sequence_单调栈

    Description

    对于一个给定的序列a1,…,an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai和ai+1用一个元素max
    (ai,ai+1)替代,这样得到一个比原来序列短的新序列。这一操作的代价是max(ai,ai+1)。进行n-1次该操作后,
    可以得到一个长度为1的序列。我们的任务是计算代价最小的reduce操作步骤,将给定的序列变成长度为1的序列。

    Input

    第一行为一个整数n( 1 <= n <= 1,000,000 ),表示给定序列的长度。
    接下来的n行,每行一个整数ai(0 <=ai<= 1, 000, 000, 000),为序列中的元素。

    Output

    只有一行,为一个整数,即将序列变成一个元素的最小代价。

    Sample Input

    3
    1
    2
    3

    Sample Output

    5

    考虑整个操作过程实际上是删除了一些数,最后只留下最大的。
    那么我们观察到i这个位置,如果a[i]不是最大的那么它会被它前面第一个或后面第一个比他大的删除,这样是更优的。
    两个取最小值,整个操作用单调栈找即可。
     
    代码:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 1000050
    int n,a[N],S[N],L[N],R[N],top;
    typedef long long ll;
    ll ans;
    int main() {
    	scanf("%d",&n);
    	int i;
    	for(i=1;i<=n;i++) {
    		scanf("%d",&a[i]);
    	}
    	S[++top]=1;
    	for(i=2;i<=n;i++) {
    		while(top&&a[S[top]]<a[i]) top--;
    		L[i]=S[top];
    		S[++top]=i;
    	}
    	top=0; S[++top]=n;
    	for(i=n-1;i;i--) {
    		while(top&&a[S[top]]<a[i]) top--;
    		R[i]=S[top];
    		S[++top]=i;
    	}
    	a[0]=1<<30;
    	for(i=1;i<=n;i++) {
    		if(L[i]==0&&R[i]==0) continue;
    		ans+=min(a[L[i]],a[R[i]]);
    	}
    	printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    P1128 [HNOI2001]求正整数
    zabbix-server端监控MySQL服务
    对服务器磁盘、CPU、内存使用状态,设置163邮件告警
    JDK8 的FullGC 之 metaspace
    JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)
    JVM的方法区和永久带是什么关系?
    如何使用start with connect by prior递归用法
    JVM原理讲解和调优
    jvm 性能调优工具之 jstat
    记一次HBase内存泄漏导致RegionServer挂掉问题
  • 原文地址:https://www.cnblogs.com/suika/p/9079159.html
Copyright © 2011-2022 走看看