cf1223 D. Sequence Sorting(dp)

题意:

数组已知。每次操作选择数组中等于某值的所有数,把它们全部移到数组首或数组尾。问至少操作几次可使数组升序。

思路:

找数组中最长的形如 \(b_1,b_1,\cdots,b_1,b_2,b_2,\cdots,b_2,\cdots\) 的序列,即值为 \(b_i\) 的数全都在值为 \(b_{i+1}\) 的数之前,且原数组中不存在大于 \(b_i\) 且小于 \(b_{i+1}\) 的数。这个序列中的数都不用操作。

记录每个不同数第一次出现和最后一次出现的位置,离散化然后dp。

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n, m, a[N], l[N], r[N], f[N];
signed main()
{
int T; cin >> T; while(T--) {
    scanf("%d", &n);

    fill(l + 1, l + 1 + n, N);
    fill(r + 1, r + 1 + n, 0);
    fill(f, f + n, 0);

    for(int i = 0; i < n; i++) scanf("%d", &a[i]),
        l[a[i]] = min(l[a[i]],i), r[a[i]] = max(r[a[i]],i);

    sort(a, a + n); m = unique(a, a + n) - a;

    int res = n;
    for(int i = 0; i < m; i++)
    {
        if(!i || l[a[i]] <= r[a[i-1]]) f[i] = 1;
        else f[i] = f[i - 1] + 1;
        res = min(res, m - f[i]);
    }

    printf("%d\n", res);
}

    return 0;
}

posted @ 2022-01-07 23:25  Bellala  阅读(65)  评论(0)    收藏  举报