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.


你可能感兴趣的:(Codeforces 584E. Anton and Ira (排列好题))