CF-1623C

Problem - 1623C - Codeforces

题意: 给出一个序列,从第三个数字开始,你可以让他减少3*d,然后让它的前两个数字,分别加2*d,和d,找出序列中的最小值的最大值。

题解: 找最小值的最大值,二分答案,关键在于check函数

  1. 由于每一个数的值都会受后两个数的影响,所以应该从后往前跑。
  2. 如果一个数本身加上后面对他的增加都不到mid,那肯定不符合,return 0。
  3. 对于每一个数,如果后面给他的数大于等于mid,那么可以直接将自身全部加到前面,如果小于,则应该将相加然后减去mid的差值加到前面,这样可以保证除了前两个以外的数字全部>=mid,然后特判一下前两个数即可。

代码:

复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=2e5+5;
const ll mod=998244353;
ll a[N],b[N];
ll minn[N],n;
bool check(ll x){
   for(ll i=1;i<=n;i++) b[i]=0;
   for(ll i=n;i>=3;i--){
    if(a[i]+b[i]>=x){
       if(b[i]>=x) b[i-1]+=a[i]/3,b[i-2]+=(a[i]/3)*2;
       else{
        ll p=a[i]+b[i]-x;
        b[i-1]+=p/3;b[i-2]+=(p/3)*2;
       }
    }
    else return 0;
   }
   return a[1]+b[1]>=x&&a[2]+b[2]>=x;
}
signed  main(){
  ll t;cin>>t;
  for(ll i=1;i<=t;i++){
    cin>>n;
    for(ll j=1;j<=n;j++){
      cin>>a[j];
    }
    ll l=1,r=1e9;
    while(l<r){
      ll mid=l+r+1>>1;
      if(check(mid)) l=mid;
      else r=mid-1;
    }
    cout<<l<<endl;
  }
}
复制代码

 

posted @   HHzp  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示