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;
}

浙公网安备 33010602011771号