G. 大树的水塘

已知每块石头中的规格是1×1×1,水塘的长度为N,宽度为1,在第i位置,大树放了ai个石头

设大树建造的水塘蓄水量为V

请你求出在长度和宽度不变的情况下,建造一个蓄水量不小于V的水塘最多可以节约多少石头

输入格式

单组输入

第一行一个数N  (1N107)表示水塘的长度

第二行有N个非负数xi  (0xi100),表示第i个位置上放的石头数

输出格式

输出有两行

第一行输出大树建造的水塘的蓄水量V

第二行输出最多可以节约多少石头

样例

input
5
2 1 3 1 3
output
3
8

提示

大树的水塘长这样:

最节约石头的水塘长这样:

题目大意就是给一组数据,求出当前的村水量,然后在求出当屯少量不少于当前屯少量时,可以节约多少石头

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1E7+7;
ll sum=0;
ll ans=0;
ll arr[N];
ll left1[N];//保存i个元素左边比最大的石头的高度
ll right1[N];//保存第i个元素右边比arr[i]大的高度 
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
//        cin>>arr[i];
        scanf("%lld",&arr[i]); 
        ans+=arr[i];
    }
    ll max_left=0,max_right=0;
    for(int i=1;i<=n;i++){
        max_left=max(max_left,arr[i]);
        left1[i]=max_left;
    }
    for(int i=n;i>=1;i--){
        max_right=max(max_right,arr[i]);
        right1[i]=max_right;
    }
    ll x;
    for(int i=1;i<=n;i++){
        x=min(left1[i],right1[i]);
        sum+=x-arr[i];    
    }
    cout<<sum<<endl; 
    if(sum%(n-2)==0){
        cout<<ans-sum/(n-2) *2<<endl;
    }
    else {
        cout<<ans-sum/(n-2)*2-2<<endl;
    } 
//    int height=ceil(1.0*sum/(n-2));//向上取整, 
//    cout<<ans-height*2<<"
";
    return 0;
}
原文地址:https://www.cnblogs.com/Accepting/p/11335451.html