这道题一开始想到处理中间是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 }