zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    洛谷P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib
    洛谷 P1062 数列
    洛谷 P2822 组合数问题
    HDU 6112 今夕何夕
    poj 2115 C Looooops
    HDU 6092 Rikka with Subset
    poj 2720 Last Digits
    poj 1254 Hansel and Grethel
    poj 1222 EXTENDED LIGHTS OUT
    poj 2459 Sumsets
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8568760.html
Copyright © 2011-2022 走看看