zoukankan      html  css  js  c++  java
  • [BOI2007] Sequence

    题目描述

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

    我们的任务是计算代价最小的reduce操作步骤,将给定的序列变成长度为1的序列。

    输入输出格式

    输入格式:

    第一行为一个整数n( 1 <= n <= 1,000,000 ),表示给定序列的长度。

    接下来的n行,每行一个整数ai(0 <=ai<= 1, 000, 000, 000),为序列中的元素。

    输出格式:

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

    输入输出样例

    输入样例#1: 
    3
    1
    2
    3
    输出样例#1: 
    5

    说明

    提示 30%的测试数据 n<=500; 50%的测试数据 n <= 20,000。

        发现只能是相邻的合并,并且一个数会在第一次与比它大的数合并时候消失,并且产生那个数的贡献。

    所以我们就找一下一个数两边第一个大于它的数,加一下两者中的较小值即可。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1000005;
    ll sum=0;
    int L[maxn],R[maxn];
    int n,a[maxn],s[maxn],tp=0;
    
    inline int read(){
    	int x=0; char ch=getchar();
    	for(;!isdigit(ch);ch=getchar());
    	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    	return x;
    }
    
    int main(){
    	scanf("%d",&n),fill(L+1,L+n+1,-1),fill(R+1,R+n+1,-1);
    	for(int i=1;i<=n;i++) a[i]=read();
    	
    	for(int i=1;i<=n;i++){
    		while(tp&&a[s[tp]]<=a[i]) tp--;
    		if(tp) L[i]=a[s[tp]];
    		s[++tp]=i;
    	}
    	tp=0;
    	for(int i=n;i;i--){
    		while(tp&&a[s[tp]]<=a[i]) tp--;
    		if(tp) R[i]=a[s[tp]];
    		s[++tp]=i;
    	}
    	
    	for(int i=1;i<=n;i++) if(L[i]>=0||R[i]>=0){
    		if(L[i]<0) sum+=(ll)R[i];
    		else if(R[i]<0) sum+=(ll)L[i];
    		else sum+=(ll)min(L[i],R[i]); 
    	}
    	
    	printf("%lld
    ",sum);
    	return 0;
    }
    

      

  • 相关阅读:
    Asp.NET 4.0 ajax实例DataView 模板编程1
    ASP.NET 4.0 Ajax 实例DataView模板编程 DEMO 下载
    部分东北话、北京话
    .NET 培训课程解析(一)
    ASP.NET 4.0 Ajax 实例DataView模板编程2
    ASP.NET Web Game 架构设计1服务器基本结构
    ASP.NET Web Game 构架设计2数据库设计
    TFS2008 基本安装
    Linux上Oracle 11g安装步骤图解
    plsql developer远程连接oracle数据库
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8810408.html
Copyright © 2011-2022 走看看