【JZOJ 4788】序列

本文探讨了一种序列调整算法,旨在通过允许序列中的每个元素上升不超过4的方式,最小化整个序列下降部分的总和。该算法采用贪心策略,通过维护一个辅助数组来跟踪最优的上升操作,从而实现O(n)的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

这里写图片描述

Solution

把题目抽象一下,就变成了求序列中,每个点可以上升4,要使下降的总和(max(0,a[i1]a[i]))最小,
首先,每个点可以上升多次!!!
当一个区间整体上升的时候,影响的就只有开头和结尾,如果要使答案减小,就要符合:

ai1ai>aj+4aj+1

于是我们可以贪心的做,用di表示不等式后面的值等于i的位置有多少个,
每次直接找到一个符合不等式的,使答案上升最小的i,加到答案上去,再di减一;

复杂度:O(n)

Code

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=100500;
int read(int &n)
{
    char ch=' ';int q=0,w=1;
    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
    if(ch=='-')w=-1,ch=getchar();
    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int n,m,ans;
int a[N],F[10];
int main()
{
    int q,_;
    read(_);
    while(_--)
    {
        read(n);
        fo(i,1,n)read(a[i]);
        fo(i,1,n)a[i]=(read(q)-a[i]+4)%4;
        F[0]=F[1]=F[2]=F[3]=0;
        a[n+1]=0;ans=a[n];
        fod(i,n,2)
        {
            F[a[i]+4-a[i+1]]++;
            fo(j,1,a[i-1]-a[i]-1)if(F[j])a[i]+=4,ans+=j,F[j]--;
            ans+=max(0,a[i-1]-a[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值