这道题一开始想到处理中间是0的位置,但这样时间太慢了,后来想到一种类似二分的方法,就是把这一段的最小值找到,全部减去最小值,然后有0一出现,就又递归处理前一段,每次答案就加上这一段的最小值;

AC代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #define maxx 100005
 4 using namespace std;
 5 int n;
 6 int block[maxx];
 7 long long ans;
 8 void go(int l,int r)
 9 {
10     if(l>r)return;
11     if(l==r){ans+=block[l];block[l]=0;return;}
12     int pos;
13     int minn=maxx;
14     for(int i=l;i<=r;i++){
15         if(block[i]<minn)
16         {
17             minn=block[i];
18             pos=i;
19         }
20     }
21     ans+=minn;
22     for(int i=l;i<=r;i++)
23         block[i]-=minn;
24     go(l,pos-1);
25     go(pos+1,r);
26 }
27 int main()
28 {
29     freopen("block.in","r",stdin);
30     freopen("block.out","w",stdout);
31     cin>>n;
32     for(int i=1;i<=n;i++)
33     scanf("%d",block+i);
34     go(1,n);
35     cout<<ans;
36     return 0;
37 }

但有个新高一的介绍了一种超厉害的方法,输入完就处理完了,每一步如果hi小于hi-1就加上差值,最后答案就是差值的和时间O(n)

AC代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #define maxx 100005
 4 using namespace std;
 5 int n;
 6 int block[maxx];
 7 long long ans;
 8 
 9 int main()
10 {
11     freopen("block.in","r",stdin);
12     freopen("block.out","w",stdout);
13     cin>>n;
14     for(int i=1;i<=n;i++)
15     {
16         scanf("%d",block+i);
17         if(block[i]>block[i-1])
18         ans+=block[i]-block[i-1];
19     }
20     cout<<ans;
21     return 0;
22 }

 

posted on 2016-07-17 19:15  李万  阅读(815)  评论(0编辑  收藏  举报