題意node
給一個長度爲\(n\)的數組,你能夠有兩種操做ios
問最小操做多少次能夠獲得一個非遞減數列c++
(比\(F1\)難在\(n\)變大,且數組中元素能夠有相同的)數組
分析spa
由於數組中的數很大,咱們能夠將其離散化而後操做,則\(a[i]\)爲連續的整數,設\(tot\)種不一樣的數,則\(1\leq a[i] \leq tot\)code
每一個數最多操做一次,不然第一次能夠不操做,那麼咱們就要找最多的不須要操做的數,若是不須要操做,則元素的位置不變,若是有這麼一組不須要操做的數,咱們能夠發現,中間的數字是不能插進去的,因此這組數是在排序後仍相鄰的數,則要找到最長的子序列,這個子序列在排序後仍然相鄰,考慮如下幾種狀況排序
設\(dp[i][0]\)爲只取相同的數且以\(a[i]\)爲結尾所獲得的最長子序列,\(dp[i][1]\)爲\(a[i]\)還沒取完且所獲得的以\(a[i]\)爲結尾最長子序列,\(dp[i][2]\)爲\(a[i]\)取完且以\(a[i]\)爲結尾所獲得的最長子序列,咱們用\(pos[i]\)表示數字\(i\)上次出現的位置,由於離散化了,因此數組能夠知足,狀態轉移方程爲(\(r[a[i]]\)表示\(a[i]\)最後出現的位置,\(l[a[i]]\)表示\(a[i]\)最先出現的位置,\(num[a[i]]\)表示\(a[i]\)的個數,\(pos[a[i]]\)表示上一個\(a[i]\)出現的位置):ci
dp[i][0] = dp[pos[a[i]]][0] + 1; dp[i][1] = max(dp[pos[a[i]]][1] + 1, max(dp[pos[a[i] - 1]][0] + 1, dp[pos[a[i] - 1]][2] + 1)); if (i == r[a[i]]) dp[i][2] = dp[l[a[i]]][1] + num[a[i]] - 1;
#pragma GCC optimize(3, "Ofast", "inline") #include <bits/stdc++.h> #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define ll long long #define int ll #define ls st<<1 #define rs st<<1|1 #define pii pair<int,int> #define rep(z, x, y) for(int z=x;z<=y;++z) #define com bool operator<(const node &b) using namespace std; mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count()); const int maxn = (ll) 2e5 + 5; const int mod = 998244353; const int inf = 0x3f3f3f3f; int T = 1; int a[maxn], b[maxn]; int dp[maxn][3]; int l[maxn], r[maxn]; int pos[maxn], num[maxn]; void solve() { int n; cin >> n; rep(i, 1, n)cin >> a[i], b[i] = a[i], dp[i][0] = dp[i][1] = dp[i][2] = 0, l[i] = r[i] = 0, num[i] = 0; sort(b + 1, b + n + 1); int tot = unique(b + 1, b + n + 1) - (b + 1); rep(i, 1, n) { a[i] = lower_bound(b + 1, b + tot + 1, a[i]) - b; r[a[i]] = i; if (!l[a[i]]) l[a[i]] = i, pos[a[i]] = i; ++num[a[i]]; } int maxx = 1; rep(i, 1, n) { dp[i][0] = dp[pos[a[i]]][0] + 1; dp[i][1] = max(dp[pos[a[i]]][1] + 1, max(dp[pos[a[i] - 1]][0] + 1, dp[pos[a[i] - 1]][2] + 1)); if (i == r[a[i]]) dp[i][2] = dp[l[a[i]]][1] + num[a[i]] - 1; pos[a[i]] = i; rep(j, 0, 2)maxx = max(maxx, dp[i][j]); } cout << n - maxx << '\n'; } signed main() { start; cin >> T; while (T--) solve(); return 0; }