• 【bzoj1345】[Baltic2007]序列问题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),为序列中的元素。

    输出

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

    样例输入

    3
    1
    2
    3

    样例输出

    5


    题解

    单调栈

    本题卡set。。。

    通过观察可以知道最优策略下,非最大值的数,一定是与它左右第一个比它大的数中较小的那个替代的。

    那么就可以使用单调栈扫出每个位置左右第一个比它大的数,然后计算即可。

    #include <cstdio>
    #include <algorithm>
    #define N 1000010
    using namespace std;
    int a[N] , v[N] , sta[N] , top;
    int main()
    {
    	int n , i;
    	long long ans = 0;
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]);
    	a[0] = a[n + 1] = 1 << 30 , top = 1;
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		while(a[i] > a[sta[top]]) top -- ;
    		v[i] = a[sta[top]] , sta[++top] = i;
    	}
    	top = 1 , sta[1] = n + 1;
    	for(i = n ; i ; i -- )
    	{
    		while(a[i] >= a[sta[top]]) top -- ;
    		v[i] = min(v[i] , a[sta[top]]) , sta[++top] = i;
    		if(v[i] != 1 << 30) ans += v[i];
    	}
    	printf("%lld
    " , ans);
    	return 0;
    }
    

     

  • 相关阅读:
    python中单例模式
    python中常用的内置方法
    面向对象之反射
    绑定方法与非绑定方法
    python多态与抽象类
    python的组合与封装
    面向对象之继承与派生
    面向对象之类与对象
    python模块与包
    数据结构与算法_语言和框架特性前瞻和bug修复
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7491569.html
Copyright © 2020-2023  润新知