• BZOJ1345 Baltic2007 序列问题Sequence 【思维题】*


    BZOJ1345 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


    其实这题比较思维

    考虑一个数的贡献

    如果他比左/右边的数大,则一定会产生这个数的贡献,并且左右边分别计算

    来想想这是为啥,我们只先考虑一边(左边)的情况

    如果这个数比左边的数小,那么无论如何这个数不会产生贡献

    如果它比左边的数大,那么考虑这个情况
    将情况化简成a,b,c三个数,其中我们在对c进行讨论

    那么如果a<c,c一定会有c的贡献
    如果a>c,这时候我们考虑先合并a,b还是b,c,最后合并a,c的贡献是定值,合并b,c的贡献显然比合并a,b要优秀,所以肯定会先合并b,c,这里产生了c的贡献

    所以前面的结论我们证明了


     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1000010
     4 int a[N],n;
     5 long long ans=0;
     6 int main(){
     7   scanf("%d",&n);
     8   for(int i=1;i<=n;i++)scanf("%d",&a[i]);
     9   for(int i=2;i<=n;i++)ans+=max(a[i],a[i-1]);
    10   printf("%lld",ans);
    11   return 0;
    12 }
  • 相关阅读:
    [pyqt4]mark
    EPC摘抄
    sockaddr struct 类型重定义
    linux编译警告 will be initialized after
    cout如何输出十六进制
    strcpy unsigned char
    c语言格式控制符
    c++字节数组转换为整型
    C++如何判断大小端
    C++中关于位域的概念
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676257.html
Copyright © 2020-2023  润新知