有 n 位員工(2 ≤ n ≤ 30),初始排隊順序與目標順序皆為 1~n 的排列。每次操作只能將隊伍中的「某一位」員工移動到隊頭。求最少操作次數使初始順序變為目標順序。
輸入:
4
2 1 3 4 // 初始順序
1 2 3 4 // 目標順序
輸出:1
解析:將員工 1 移到隊頭即可:[2,1,3,4] → [1,2,3,4]
關鍵洞察:從目標順序逆推,找出最長的「已經有序」尾部子序列。
prevPos 變數,初始為無限大< prevPos,說明相對順序正確,更新 prevPos 並繼續#include <bits/stdc++.h>
using namespace std;
int main() {
int T; cin >> T;
while (T--) {
int n; cin >> n;
vector init(n), target(n), pos(n+1);
for (int i = 0; i < n; ++i) { cin >> init[i]; pos[init[i]] = i; }
for (int i = 0; i < n; ++i) cin >> target[i];
int prevPos = n; // 初始設為超出範圍
int orderedSuffix = 0;
for (int i = n-1; i >= 0; --i) {
if (pos[target[i]] < prevPos) {
prevPos = pos[target[i]];
orderedSuffix++;
} else break;
}
cout << (n - orderedSuffix) << endl;
}
return 0;
}
原最佳回答給出的選擇排序程式碼完全錯誤,該題不是排序問題,而是在特定操作限制下的最小操作數問題。選擇排序的交換操作與「移到隊頭」本質不同,切勿混淆。
樣例 2:
3
2 1 3
3 1 2
初始位置:2→0, 1→1, 3→2
目標從右掃:2(pos=1<3)✓, 1(pos=1<1)✗ 中斷
有序尾部長度=1,答案=3-1=2 ✓