• codefroces 946G Almost Increasing Array


    Description
    给你一个长度为$n$的序列$A$.现在准许你删除任意一个数,删除之后需要修改最小的次数使序列单调递增。问最小次数。
    $1≤n≤200000$
    Examples
    Input
    5
    5 4 3 2 1
    Output
    3
    Input
    5
    1 2 8 9 5
    Output
    0

    因为是修改形成递增,所以假设修改$l+1~r-1$,那么要求$a[r]-a[l]-1>=r-l-1$

    于是有$a[r]-r>=a[l]-l$

    于是就转化为求最长不下降子序列

    因为可以删一个点,删掉的点的后面的值减去的位权-1

    设$f[i][0/1]$为第i位,是否删了点

    用二分优化,重新令$f[i][0/1]$表示长为i的序列末尾最小的数,是否删点

    注意删了点的话位置会向前移,所以由$a[i]-i$变成$a[i]-i+1$

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 int inf=1e9,f[200005][2],a[200005],b[200005],n,tot,ans;
     8 int find(int x,int p)
     9 {
    10   int l=1,r=n,as=0;
    11   while (l<=r)
    12     {
    13       int mid=(l+r)/2;
    14       if (f[mid][p]>x)as=mid,r=mid-1;
    15       else l=mid+1;
    16     }
    17   return as;
    18 }
    19 int main()
    20 {int i,tmp1,tmp2;
    21   cin>>n;
    22   for (i=1;i<=n;i++)
    23     {
    24       scanf("%d",&a[i]);
    25       f[i][0]=f[i][1]=inf;
    26     }
    27   f[0][0]=f[0][1]=-inf;
    28   for (i=2;i<=n;i++)
    29     {
    30       tmp1=find(a[i-1]-i+1,0);tmp2=find(a[i]-i+1,1);
    31       f[tmp1][0]=a[i-1]-i+1;
    32       f[tmp2][1]=a[i]-i+1;
    33       f[tmp1][1]=min(f[tmp1][1],f[tmp1][0]);
    34       ans=max(ans,max(tmp1,tmp2));
    35     }
    36   cout<<n-ans-1;
    37 }
  • 相关阅读:
    深入浅出列生成算法
    小游戏云开发入门
    代码生成器插件与Creator预制体文件解析
    使用四叉树优化碰撞检测
    游戏开发中的人工智能
    一个可屏蔽长短链接的网络模块
    游戏开发中的新手引导与事件管理系统
    Creator填色游戏的一种实现方案
    CocosCreator之AssetBundle使用方案分享
    跨引擎游戏框架说明文档
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8568760.html
Copyright © 2020-2023  润新知