CodeForces 1367F1 Flying Sort (Easy Version)

題意node

給一個長度爲\(n\)的數組,數組中的數互不相同,你能夠有兩種操做ios

  • 將某一個數放置在數組開頭
  • 將某一個數放置在數組結尾

問最小操做多少次能夠獲得一個遞增數列c++

分析數組

由於數組中的數很大,咱們能夠將其離散化而後操做,這樣咱們能夠獲得一個長度爲\(n\)的排列,目的是獲得一個從\(1\)\(n\)的順序排列spa

每一個數最多操做一次,不然第一次能夠不操做,那麼咱們就要找最多的不須要操做的數,若是不須要操做,則元素的位置不變,若是有這麼一組不須要操做的數,咱們能夠發現,中間的數字是不能插進去的,因此這組數是相鄰的數,那麼問題就轉換爲找到數組內最長的相差爲\(1\)的子序列,考慮用\(DP\)\(dp[i]\)表示以數字\(i\)爲結尾的最長子序列長度,則轉移方程爲code

\[dp[a[i]]=dp[a[i]-1]+1 \]

若是\(a[i]-1\)出現了,則這個數是\(a[i]-1\)的後綴,不然這個數是開頭,即爲\(1\)ci

#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) 3e3 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
int T = 1;
int a[maxn], b[maxn];
int dp[maxn];

void solve() {
    int n;
    cin >> n;
    map<int, int> mp;
    rep(i, 1, n)cin >> a[i], b[i] = a[i], mp[a[i]] = i, dp[i] = 0;
    sort(b + 1, b + n + 1);
    rep(i, 1, n)a[mp[b[i]]] = i;
    int maxx = 1;
    rep(i, 1, n) {
        dp[a[i]] = dp[a[i] - 1] + 1;
        maxx = max(maxx, dp[a[i]]);
    }
    cout << n - maxx << '\n';
}

signed main() {
    start;
    cin >> T;
    while (T--)
        solve();
    return 0;
}
相關文章
相關標籤/搜索