G. 大树的水塘

Posted accepting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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<<"\n";
    return 0;

 

以上是关于G. 大树的水塘的主要内容,如果未能解决你的问题,请参考以下文章

水塘抽样算法

LeetCode 398 随机数索引[水塘抽样] HERODING的LeetCode之路

水塘抽样(Reservoir Sampling)问题

java 水塘采样

Shuffle an Array (水塘抽样)

利用水塘抽样来解决“随机数索引“问题