AmazingCounters.com

Vijos1615 旅行

传送门@百度

背景

Orz4-1 travel

描述

今天是个神圣的日子,因为LHX教主要进行一段长途旅行。但是教主毕竟是教主,他喜欢走自己的路,让别人目瞪口呆。为什么呢,因为这条路线高低不平,而且是相当的严重。

但是教主有自己的办法,他会魔法。

这段路可以用一个长度为N的序列A[I]来表示,A[I]表示了第I这段路的高度。毕竟教主即使会使用魔法他还是个人,教主如果想穿越这条路线,他 必须从第1段路开始走,走到第N段,从第I段走到第I+1段路需要消耗|A[I+1]-A[I]|点体力。为了节省体力,教主使出了他神奇的魔法。教主的 魔法可以将一段路高度变高或者变低,但是使用魔法也需要体力,改变一段路H的高度就需要消耗H的体力。即若教主把第I段路高度从A[I]变成了K,那么他 需要消耗|A[I]-K|点体力。

接着,LHX教主想规划下如何调整路段高度后穿越,使得总体力消耗最小。

格式

输入格式

输入的第1行为一个正整数N,表示了这条路线的长度。

第2行有N个正整数,相邻两个正整数用空格隔开,描述了A[I]这个序列。

输出格式

输出仅包括一个非负整数,为最小的总体力消耗。

注意:答案可能超过2^31-1,请使用int64或者long long类型保存答案。

样例1

样例输入1[复制]

3
3 4 1

样例输出1[复制]

3

限制

对于10%的数据,有N≤10;
对于30%的数据,有A[I]≤1000;
对于40%的数据,有N≤1000;
对于100%的数据,有N≤100000,A[I]≤10000000。

时限1s。

提示

将第2段路的高度调整为3,第3段路的高度调整为2,调整体力消耗为2。

路线序列变为3 3 2,穿越这条路线消耗体力为1。

所以总体力消耗为3。

 

有了noip2013的教训。。现在学会从贪心的角度考虑问题了。。

这个显然找拐点就行

#include<set>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100100;
#define Rep(i,n) for(int i=1;i<=n;i++)
#define For(i,l,r) for(int i=l;i<=r;i++)

int n,A[N];
long long ans;

int main(){
    freopen("travel.in","r",stdin);
    freopen("travel.out","w",stdout);
    scanf("%d",&n);
    Rep(i,n) scanf("%d",&A[i]);
    For(i,2,n-1){
        if(A[i-1]<A[i]&&A[i]>A[i+1]){
            ans+=A[i]-max(A[i-1],A[i+1]);
            A[i]=max(A[i+1],A[i-1]);
        }
        if(A[i-1]>A[i]&&A[i]<A[i+1]){
            ans+=min(A[i-1],A[i+1])-A[i];
            A[i]=min(A[i+1],A[i-1]);
        }
    }
    For(i,2,n) ans+=abs(A[i]-A[i-1]);
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2014-10-06 19:34  ZJDx1998  阅读(262)  评论(0编辑  收藏  举报