CodeForces 584E Anton and Ira

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 ≤ n, i ≠ j), which means that you need to swap pi 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.



好题!

题目大意,给两个数列,x,和y,每交换一次x的代价是|i-j|,问花费最少将x变成y需要几步,代价一共多少,分别是哪几步?

方法:先通过映射,将Y转换为1 2 3 4 ....正序序列,再用映射关系把X也对应转换,然后yy一个结论


例如样例的数据

将3 2 4 1映射成1 2 3 4

则f(3)=1,f(2)=2,f(4)=3,f(1)=4;

则X序列此时就变成3 2 4 1

那把 3 2 4 1通过交换变成 1 2 3 4的代价结果和样例中所求的答案是相同的

然后是结论:

越大的数,应当是放在越靠后的位置的

for循环i从最大的开始,遇到正确的位置数i==x[i]的就跳过

每次找到X当前数中==最大数的位置

把这个位置pos记下来,因为要处理的就是这个位置的数,目的就是将这个位置的数变成X[i].

然后找到哪里去交换这个pos位置的数

其实很简单,就是贪心

for循环从j=pos+1的位置开始找,保证后面X数的位置j一定比当前要处理的数的位置pos要大,显然.

那为了代价最小,就优先让在j后面位置的但不大于pos位置数(也就是小于等于我们要处理的那个数)和pos位置交换

因为pos的数是当前最大的,早晚都是要滚去最后面的。

所以他pos后面的数都应当排在pos前面

交换后将代价累加即可,保存交换的两个位置即可


#include <stdio.h>
#include <algorithm>
using namespace std;
const int MAXN=2005;
int x[MAXN];
int y[MAXN];
int f[MAXN];
int ansi[MAXN*MAXN];
int ansj[MAXN*MAXN];
int main()
{
        int n,cnt=0,sum=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
                scanf("%d",&x[i]);
        for(int i=1;i<=n;i++)
        {
                scanf("%d",&y[i]);
                f[y[i]]=i;
        }
        for(int i=1;i<=n;i++)
                x[i]=f[x[i]];
        for(int i=n;i>=1;i--)
        {
                if(x[i]==i)
                        continue;
                int pos;
                for(int j = 1; j <= n; j++)
                {
                        if(x[j] == i)
                        {
                                pos = j;
                                break;
                        }
                }
                int j=pos+1;
                for(int j=pos+1;pos!=i;j++)
                {
                        if(pos>=x[j])
                        {
                                ansi[cnt]=pos;
                                ansj[cnt++]=j;
                                sum+=(j-pos);
                                swap(x[pos],x[j]);
                                pos=j;
                                j--;
                        }
                }
        }
        printf("%d\n%d\n",sum,cnt);
        for(int i=0;i<cnt;i++)
                printf("%d %d\n",ansi[i],ansj[i]);
        return 0;
}


### Codeforces 887E Problem Solution and Discussion The problem **887E - The Great Game** on Codeforces involves a strategic game between two players who take turns to perform operations under specific rules. To tackle this challenge effectively, understanding both dynamic programming (DP) techniques and bitwise manipulation is crucial. #### Dynamic Programming Approach One effective method to approach this problem utilizes DP with memoization. By defining `dp[i][j]` as the optimal result when starting from state `(i,j)` where `i` represents current position and `j` indicates some status flag related to previous moves: ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = ...; // Define based on constraints int dp[MAXN][2]; // Function to calculate minimum steps using top-down DP int minSteps(int pos, bool prevMoveType) { if (pos >= N) return 0; if (dp[pos][prevMoveType] != -1) return dp[pos][prevMoveType]; int res = INT_MAX; // Try all possible next positions and update 'res' for (...) { /* Logic here */ } dp[pos][prevMoveType] = res; return res; } ``` This code snippet outlines how one might structure a solution involving recursive calls combined with caching results through an array named `dp`. #### Bitwise Operations Insight Another critical aspect lies within efficiently handling large integers via bitwise operators instead of arithmetic ones whenever applicable. This optimization can significantly reduce computation time especially given tight limits often found in competitive coding challenges like those hosted by platforms such as Codeforces[^1]. For detailed discussions about similar problems or more insights into solving strategies specifically tailored towards contest preparation, visiting forums dedicated to algorithmic contests would be beneficial. Websites associated directly with Codeforces offer rich resources including editorials written after each round which provide comprehensive explanations alongside alternative approaches taken by successful contestants during live events. --related questions-- 1. What are common pitfalls encountered while implementing dynamic programming solutions? 2. How does bit manipulation improve performance in algorithms dealing with integer values? 3. Can you recommend any online communities focused on discussing competitive programming tactics? 4. Are there particular patterns that frequently appear across different levels of difficulty within Codeforces contests?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值