CF1898B Milena and Admirer

题目链接

题目大意

给出一个长度为 $n(1 \leq n \leq 2*10^5)$ 的数组 $a_i(1 \leq a_i \leq 10^9)$ ,你可以将数组中任意一个数 $a_i$ 分成两个数 $x,a_i-x$ ,求使该数组非严格递增的最小操作数

思路

容易发现,无论如何操作,数组中的数都会小于等于数组中最后一个数并大于等于第一个数

所以可以贪心的从后往前遍历数组,碰到 $a{i-1} > a_i$ 的情况就分裂 $a{i-1}$ ,这时候为了确保后续操作数更少,我们需要让分裂出的最小数尽可能大,所以不妨考虑将 $a{i-1}$ 尽可能平均分成 $x$ 份,此时分裂出的数保证最大数 $\frac{a{i-1}+a{i-1}\%x}{x} \leq a_i$ ,最小数 $\frac{a{i-1}-a{i-1}\%x}{x} \geq a{i-2}$ 即可

代码

#include<bits/stdc++.h>
#define int long long
#define in inline
#define ri register
#define _123hh2 0
using namespace std;
in int read()
{
    int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x*f;
}
in void write(int x) {if(x<0) {x=-x;putchar('-');}if(x>9) write(x/10);putchar(x%10+'0');}
const int maxn=2e5+1;
int awa[maxn];
signed main()
{
    int  t=read();
    while(t-->0)
    {
        int n=read(),now,cnt=0;
        for(int i=1;i<=n;i++) awa[i]=read();
        now=awa[n];
        for(int i=n-1;i>=1;i--)
        {
            if(awa[i]>now)
            {
                int x=awa[i]/now-1;
                if(awa[i]%now) x++;
                cnt+=x;
                now=awa[i]/(x+1);
            }
            else now=awa[i];
        }
        write(cnt),puts("");
    }
    return _123hh2;
}
更新于

请我喝[茶]~( ̄▽ ̄)~*

123hh2 微信支付

微信支付

123hh2 支付宝

支付宝

123hh2 贝宝

贝宝