排列轉換
阿新 • • 發佈:2017-08-20
() 題目 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);
}
排列轉換