cf1623 Round #763 Div2-C【二分+贪心】

该博客讨论了一道编程题目,涉及使用二分查找和贪心策略来解决关于数组元素分配的问题。题目要求在满足特定条件的情况下,最大化n个元素中的最小值。博主分享了其理解题意的难点,解析了错误理解,并提供了AC代码实现。通过从后往前的贪心策略,检查二分查找的答案是否合法,最终找到满足条件的最大最小值。
摘要由CSDN通过智能技术生成

Date:2021.12.28

题意:n个元素,第i个元素可以分给第i-1个元素d,分给第i-2个元素2 * d(前提是第i个能分出3 * d),求分配若干次后n个元素中最小值最大是多少。
我们先来看下原题:
在这里插入图片描述

思路:二分答案,如何check?
首先,一个元素只会影响它前面的两个元素,因此我们从后往前来想,我们每次二分答案为mid,从最右面的元素开始贪心的减,即保证>=mid的前提下分出最多的给前面两个。如果遍历到任一元素<mid,则说明mid大了应该变小,并且当前mid也不合法。我们还是看下原题意,个人觉得题意不是很明确,具体来说划线处含义为:每个位置上最大可移动的数不超过“原序列中每一项的 h i h_i hi”,我一直以为 h i h_i hi是变动的因此每个位置上最大可移动的数也是变动的,所以1号样例的第一个一直是15,坑死人了。
代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5+10;
LL n,m,k,t;
LL a[N],b[N],c[N];
bool st[N];
bool check(LL mid)
{
    for(int i=1;i<=n;i++) b[i]=a[i];
    for(int i=n;i>=3;i--)
    {
        if(b[i]<mid) {return false;}
        else
        {
            LL d=min(b[i]-mid,a[i])/3;
            b[i-1]+=d;b[i-2]+=2*d;
        }
    }
    if(b[2]>=mid&&b[1]>=mid) return true;
    else return false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--)
    {
        LL maxx=0;
        cin>>n;for(int i=1;i<=n;i++) {cin>>a[i];maxx=max(maxx,a[i]);}
        LL l=1,r=maxx;
        while(l<r)
        {
            int mid=l+r+1>>1;
            //cout<<mid<<' ';
            if(!check(mid)) r=mid-1;
            else l=mid;
        }
        cout<<l<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值