【题目来源】
http://oj.ecustacm.cn/problem.php?id=1812
http://oj.ecustacm.cn/viewnews.php?id=1023
【题目描述】
给定一个长度为 n 的排列 a,需要将这个排列变成 b。
每次可以选择一个数字往左移若干个位置。
请求出最小需要移动的元素个数。
【输入格式】
第一行为正整数 n,1≤n≤100000。
第二行为 n 个整数,表示排列 a。
第三行为 n 个整数,表示排列 b。
【输出格式】
输出一个数字表示答案,即最小需要移动的元素个数。
【输入样例】
5
5 1 3 2 4
4 5 2 1 3
【输出样例】
2
【算法分析】
** 将原序列 a 重排为序列 b,则原序列 a 中各元素在序列 b 中的位置 p[] 可通过以下代码获得:
tp[b[i]]=i, p[i]=tp[a[i]]
** 分析位置序列 p[] 中每个数,如果当前的数比左边的数小就不断左移,否则不用移动。这是贪心算法的思路。
例如,针对样例中给出的原始序列 a[]=[5 1 3 2 4] 中的各元素,利用“tp[b[i]]=i, p[i]=tp[a[i]]”,可得出它们在重排序列 b[]=[4 5 2 1 3] 中的位置序列为 p[]=[2 4 5 3 1]。显然,通过观察位序的相对位置,可知需要移动两个数字。
【算法代码】文章来源:https://www.toymoban.com/news/detail-660776.html
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],b[N];
int p[N]; //p[x]:subscript of number x in the b array
int tp[N];
int main() {
int n;
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1; i<=n; i++) {
cin>>b[i];
tp[b[i]]=i;
}
for(int i=1; i<=n; i++) p[i]=tp[a[i]];
int ans=0;
int t=0;
for(int i=1; i<=n; i++) {
if(t>p[i]) ans++;
t=max(t,p[i]);
}
cout<<ans<<endl;
return 0;
}
/*
in:
5
5 1 3 2 4
4 5 2 1 3
out:
2
*/
【参考文献】
https://blog.csdn.net/weixin_43914593/article/details/131741061
文章来源地址https://www.toymoban.com/news/detail-660776.html
到了这里,关于罗勇军 → 《算法竞赛·快冲300题》每日一题:“排列变换” ← 贪心算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!