排列转换

排列转换

现在有两个长度为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);
}
时间: 2024-10-14 15:59:46

排列转换的相关文章

51nod 1574 排列转换(贪心+鸽巢原理)

题意:有两个长度为n的排列p和s.要求通过交换使得p变成s.交换 pi 和 pj 的代价是|i-j|.要求使用最少的代价让p变成s. 考虑两个数字pi和pj,假如交换他们能使得pi到目标的距离减少,pj到目标的距离减少.那么应该交换他们,这是一个必要的操作,也是答案的下界. 如果每一次都能找到这样的两个数字,那么答案就是排列p中的每个数字在排列s的位置的距离差之和/2.这显然是答案的下界. 现在考虑证明这个下界是可以构造出来的. 考虑排列p中最后一个位置不对的数字,不妨设为pj,他的目标位置是p

51nod 1574 排列转换

分析: 大佬们也有搞错的时候,说把s重排一下,求逆序数对就行了: 这个是相邻两两交换: 正解: 是将所有没有在正确位置的数,他们一次性到达他正确的位置,没有浪费: 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 200000 + 5; 6 int a[maxn]; 7 int b[maxn]; 8 bool vis[maxn]; 9 10 int main() 11 { 12 int n; 13

文本相似度计算基本方法小结

在计算文本相似项发现方面,有以下一些可参考的方法.这些概念和方法会帮助我们开拓思路. 相似度计算方面 Jaccard相似度:集合之间的Jaccard相似度等于交集大小与并集大小的比例.适合的应用包括文档文本相似度以及顾客购物习惯的相似度计算等. Shingling:k-shingle是指文档中连续出现的任意k个字符.如果将文档表示成其k-shingle集合,那么就可以基于集合之间的 Jaccard相似度来计算文档之间的文本相似度.有时,将shingle哈希成更短的位串非常有用,可以基于这些哈希值

15-谜问题

问题描述: 在一个分成16格的方形棋盘上,放有15块编了号码的牌.对这些牌给定一种初始排列,要求通过一系列的合法移动将这一初始排列转换成目标排列. 这个问题解决时用到了L-C检索.在检索的过程中计算估值函数c(x)=f(x)+g(x); 通过比较估值函数确定遍历的方向.L-C检索是有智力的搜索. package lc_search; public class Riddle_15 { Riddle_15(){} public class A implements Cloneable{ //棋盘的抽

CSS3弹性盒模型 display:box

刚开始做网页时就有一个困惑,为什么display:block只能垂直排列,如果要水平排列就要使用float:left等方式.这种方法最难受的当然是当子元素的数量改变时,需要去修改子元素的宽度使重新适应.bootstrap为了兼容性在实现栅格布局时,就不得不生成大量如下代码: .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .

cf1143E 倍增好题!

一开始感觉用莫队可以搞一下,但是看了题解才发现这题其实是倍增套路题 把排列转换成nxt数组,然后倍增dp[i][j]表示第i个数后面有(1<<j)个数的最靠左的区间 然后从右往左扫一次即可 #include<bits/stdc++.h> using namespace std; #define maxn 200005 int dp[maxn][20],last[maxn],nxt[maxn],ans[maxn],a[maxn],b[maxn],n,m,t; //dp[i][j]表示

搜索入门练习题2 全排列 题解

题目出处:课程=>搜索1=>题目A 题目描述 给定一个正整数 \(n\) ,按照递增顺序打印数字 \(1\) 到 \(n\) 的所有排列. 输入格式 一个整数 \(n(1 \le n \le 7)\) . 输出格式 按照递增顺序输出 \(n\) 个数的所有排列,每行代表一组排列, \(n\) 个数两两之间有一个空格分隔. 样例输入 3 样例输出 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 问题分析 这是一道搜索的题目. 我们知道搜索就是状态到状态之间的转换,其本质是

字节序转换与结构体位域(bit field)值的读取 Part 2 - 深入理解字节序和结构体位域存储方式

上一篇文章讲解了带位域的结构体,在从大端机(Big Endian)传输到小端机(Little Endian)后如何解析位域值.下面继续深入详解字节序,以及位域存储的方式. (1) 我们知道,存储数字时,对小端机而言,数字的低位,存在低地址,高位存在高地址.大端机正相反. (2) 读取的方式,也是一样的.对于小端机,读出的低地址位作为数字的低位. (3) 此外Big-Endian/Little-Endian存储顺序,不仅仅针对字节,还针对字节内的比特位.对于小端机而言,字节内的8个比特,低地址端比

计算机进制转换

一.计算机只认识0和1,二进制. 二.2进制转换成 8进制 和 16进制,如下图: 二进制 > 八进制 :  研究上图发现,3位最高二进制可以用来表示一位八进制.所以,将二进制分解每3位,不够前面补0,然后每3位转换为10进制,顺序排列即可. 二进制 > 十六进制  :4位最高二进制可以用来表示一位十六进制.所以,将二进制分解每4位,不够前面补0,然后每4位转换为10进制,超过9用字母表示即可.顺序排列即可. 如下: 二进制 > 十进制:   11001001 = 2^7+2^6+2^3