Codeforces 584E. Anton and Ira (排列好題)

大致題意: n <= 2000,有一1~n的排列p和s,對pi和pj交換產生的代價是 | i - j | , 問最少需要多少代價使,排列p變成排列s,輸出解

思路:

可以先把s映射成1...n的規則排列,然後再把p序列對應映射成新的序列(這樣便於分析和思考,得到的問題與原問題等價)

先對每個元素考慮,設pi和pj交換產生的代價是 2 * | i - j | (即pi和pj各產生了|i-j|的代價) 

對於p中的每個pi,最終都是需要把i位置的pi換到pi位置,至少需要的代價| i - pi | , 然而答案就是最小的代價的和,結論有美感


構造證明:對任何pi從pos1=i 調換到pos2=pi的過程中可以使調換的兩個值都更逼近於s(不增加任何代價)

可以這樣構造調換:

按大到小一一安放位置(pi = n~1)

pos:i~pi中必有一個px  <= i,這樣就可以交換pi和px,再從x位置繼續交換到pi位置,因爲1...i位置中最多i-1個值<=pos(因爲pi一定大於i) ,再由鴿巢原理得證


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
#define rep(i,n) for ( int i=0; i< int(n); i++ )
using namespace std;
typedef long long ll;
#define X first
#define Y second
#define PB push_back
#define MP make_pair
typedef pair<int,int> pii;

template <class T>
inline bool RD(T &ret) {
        char c; int sgn;
        if (c = getchar(), c == EOF) return 0;
        while (c != '-' && (c<'0' || c>'9')) c = getchar();
        sgn = (c == '-') ? -1 : 1 , ret = (c == '-') ? 0 : (c - '0');
        while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return 1;
}
template <class T>
inline void PT(T x) {
        if (x < 0) putchar('-') ,x = -x;
        if (x > 9) PT(x / 10);
        putchar(x % 10 + '0');
}
const int N = 2e3+100;
int a[N];
int b[N];
int trans[N];
int vs[N];
vector<pii> res;
int main() {
	int n;
	RD(n);
	REP(i, n) RD(a[i]);
	REP(i, n) RD(b[i]), trans[b[i]] = i;
	int ans = 0;
	REP(i, n) a[i] = trans[a[i]], vs[a[i]] = i;
	for(int num = n; num >= 1; num--) {
		int pos = vs[num];
		if(pos == num) continue;
		for(int i = pos; i <= num; i++) {
			if(a[i] <= pos ) {
				ans += i - pos;
				swap(vs[a[i]], vs[a[pos]]);
				swap(a[i], a[pos]);
				res.PB(pii(i, pos));
				pos = i;
			}
		}
	}
	cout << ans << endl;
	printf("%d\n", SZ(res) );
	foreach(it, res) printf("%d %d\n", (*it).X, (*it).Y);
}









E. Anton and Ira
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Anton loves transforming one permutation into another one by swapping elements for money, and Ira doesn't like paying for stupid games. Help them obtain the required permutation by paying as little money as possible.

More formally, we have two permutations, p and s of numbers from 1 to n. We can swap pi and pj, by paying |i - j| coins for it. Find and print the smallest number of coins required to obtain permutation s from permutation p. Also print the sequence of swap operations at which we obtain a solution.

Input

The first line contains a single number n (1 ≤ n ≤ 2000) — the length of the permutations.

The second line contains a sequence of n numbers from 1 to n — permutation p. Each number from 1 to n occurs exactly once in this line.

The third line contains a sequence of n numbers from 1 to n — permutation s. Each number from 1 to n occurs once in this line.

Output

In the first line print the minimum number of coins that you need to spend to transform permutation p into permutation s.

In the second line print number k (0 ≤ k ≤ 2·106) — the number of operations needed to get the solution.

In the next k lines print the operations. Each line must contain two numbers i and j (1 ≤ i, j ≤ ni ≠ j), which means that you need to swappi and pj.

It is guaranteed that the solution exists.

Sample test(s)
input
4
4 2 1 3
3 2 4 1
output
3
2
4 3
3 1
Note

In the first sample test we swap numbers on positions 3 and 4 and permutation p becomes 4 2 3 1. We pay |3 - 4| = 1 coins for that. On second turn we swap numbers on positions 1 and 3 and get permutation 3241 equal to s. We pay |3 - 1| = 2 coins for that. In total we pay three coins.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章