1715: 序列变换(LIS变形)

博客围绕数列严格递增问题展开,给定数列,要求修改最少元素使其严格递增,元素须为整数。介绍了输入输出格式,指出这是最长上升子序列的变形,给出预处理方法及因数据大需用基于贪心的O(nlogn)解法。

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

1715: 序列变换
时间限制: 1 Sec 内存限制: 128 MB

[提交][状态][讨论版]
题目描述
我们有一个数列A1,A2…An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。
请输出最少需要修改多少个元素。
输入
第一行输入一个N(1≤N≤10e5),表示数列的长度
第二行输入N个数A1,A2,…,An。
每一个数列中的元素都是正整数而且不超过10e6。
输出
输出最少需要修改多少个元素
样例输入

3
2 5 4

样例输出

1

提示
来源
/*
最长上升子序列的变形。
每个元素都必须为整数(正,负都行)
对于:
9
2 2 3 3 4 4 5 5 6
ans = 7
---->-1 2 3 4 5 6 7 8 9
当aj > ai 时,i < j,i与j之间的元素要也要严格递增,得满足这个条件:
aj-ai >= j-i
整理上式:
aj - j >= ai - i
所以可以对原序列预处理一下,nowValue = oldValue-index
然后本题数据比较大不呢之间用O(n^2)解法,只能用基于贪心的O(nlogn)解法
*/

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int a[maxn];
int st[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        cin>>a[i];
        a[i] = a[i] - i;
    }
    int t = 0;
    st[t] = -(1<<30);
    for(int i = 0; i < n; i++)
    {
        // a[i] - a[j] >= i-j;-->a[i]-i >= a[j]-j,i>j
        if(a[i] >= st[t])
        {
            st[++t] = a[i];
        }
        else
        {
           //可以直接用upper_bound,但是我更喜欢自己写二分
           // int pos = upper_bound(st,st+t+1,a[i])-st;
           //st[pos] = a[i];
            int left = 1, right = t;
            while(left <= right)
            {
                int mid = (left+right)>>1;
                if(a[i] >= st[mid])
                {
                    left = mid + 1;
                }
                else
                {
                    right = mid - 1;
                }
            }
            st[left] = a[i];
        }
    }
    cout<<n-t<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Enco-Lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值