1. 程式人生 > >排列轉換

排列轉換

() 題目 input 出現一次 lis -1 .org mat tar

排列轉換

現在有兩個長度為n的排列p和s。要求通過交換使得p變成s。交換 pipi 和 pjpj 的代價是|i-j|。要求使用最少的代價讓p變成s。


Input單組測試數據。
第一行有一個整數n (1≤n≤200000),表示排列的長度。
第二行有n個範圍是1到n的整數,表示排列p。每個整數只出現一次。
第三行有n個範圍是1到n的整數,表示排列s。每個整數只出現一次。Output輸出一個整數,表示從排列p變到s最少要多少代價。

Sample Input

樣例輸入1
4
4 2 1 3
3 2 4 1

Sample Output

樣例輸出1
3

題目大意 :給你一初始組序列和一組既定序列,求從初始序列到既定序列所用最小的|i-j|值的和。

題目分析 :

  考慮排列p中最後一個位置不對的數字,不妨設為pj,他的目標位置是pi,那麽如果p[i+1,j]中有任意一個數的目標是pk(k<i),那麽可以進行必要交換。

  假設沒有這樣的一個數字使得他的目標是pk,一共有(j-i-1)個數,(j-i-2)個空,根據鴿巢原理,顯然不存在這樣的情況。

  也就是說,對於排列p中最後一個位置不對的數字pj,目標位置是pi,pi總能在p[i+1,j]中找到一個數字pk,使得它們交換之後到目標的距離都減小了。

 題目收獲 :仍存疑問。

AC代碼:

#include <iostream>
#include <cstdio>
#include 
<math.h> using namespace std; int ans[200005]; int main() { int n, x; long long sum = 0; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &x), ans[x] = i; for (int i = 1; i <= n; i++) { int y = 0; scanf("%d", &y); sum
+= abs(ans[y] - i); } printf("%lld\n", sum / 2); }

排列轉換