luogu P1091 单调序列版

心血来潮水一篇题解luogu竟然关了这题的提交…苦鲁西

本茍蒻的思路是遍历每个数组元素,分别找出她左右(包括她自己)的最长严格降序的长度,相加减一(因为“她”加了两次), 答案就是其最大值

Code

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = (int)l; i <= (int)r; i++)
#define dep(i, r, l) for (int i = (int)r; i >= (int)l; i--)
int a[105], l[105], r[105];
int n,ma;
int main()
{
  cin >> n;
  rep(i, 1, n)cin >>a[i];
  rep(i, 1, n)
  //这个地方我本来是rep(i,2,n-1)然后有个点没过…
  //原来不用严格a<b>c,a<b<c||a>b>c也是可以的
  {
    memset(l, 0, sizeof l),memset(r, 0, sizeof r);
    int llen = 0, rlen = 0;
    l[++llen] = a[i], r[++rlen] = a[i];
    dep(j,i-1,1) 
    {
      if (a[j] < l[llen])//找前面小于i的数,将其存在单调数组l中,顺便更新llen
        l[++llen] = a[j];
      else//否则就更新l数组的值,尽量使得l数组的最后一个数较大
      {
        if (a[j] >= l[1])//如果原数组后面元素大于等于l[1],则不可能将其放进单调数组l中
          continue;
        int id = lower_bound(l + 1, l + 1 + n, a[j], greater<int>()) - l;
        //默认的lower_bound是单调上升的,可以在后面加个greater<int>(),将其变为单调下降的
        
        /* 也可以不用stl
        int id = llen;
        while (l[id] <= a[j])
          id--;id++;
        */
        
        l[id] = a[j];
      }
    }
    rep(j, i + 1, n)
    {
      if (a[j] < r[rlen])//找后面小于i的数,将其存在单调数组r中,顺便更新rlen
        r[++rlen] = a[j];
      else//否则就更新l数组的值,尽量使得r数组的最后一个数较大
      {
        if (r[1] <= a[j])//如果原数组后面元素大于等于r[1],则不可能将其放进单调数组r中
          continue;
        int id = lower_bound(r + 1, r + 1 + rlen, a[j], greater<int>()) - r;
        
        /* 也可以不用stl        
        int id = rlen;
        while (r[id] <= a[j])
          id--;id++;
        */
        
        r[id] = a[j];
      }
    }
    ma = max(ma, llen + rlen - 1);
    //两数组相加减去重复的第一个数(a[i]
  }
  cout << n - ma;
  return 0;
}

QwQ

上一篇:luogu P2597 [ZJOI2012]灾难


下一篇:luogu P5055 【模板】可持久化文艺平衡树