罗勇军 → 《算法竞赛·快冲300题》每日一题:“排列变换” ← 贪心算法

【题目来源】
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\[\]++ 可通过以下代码获得:
tpb\[i]=i, pi=tpa\[i]
** 分析位置序列 p\[\] 中每个数,如果当前的数比左边的数小就不断左移,否则不用移动。这是贪心算法的思路。
例如,针对样例中给出的原始序列 a\[\]=5 1 3 2 4 中的各元素,利用"tpb\[i]=i, pi=tpa\[i]",可得出它们在重排序列 b\[\]=4 5 2 1 3 中的位置序列为 p\[\]=2 4 5 3 1。显然,通过观察位序的相对位置,可知需要移动两个数字。

【算法代码】

cpp 复制代码
#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

相关推荐
耶叶20 小时前
餐厅出入最少人数问题:贪心算法
算法·贪心算法
散峰而望1 天前
【算法练习】算法练习精选:陶陶摘苹果(基础+升级)、Music Notes、字串变换,你能AC几道?
数据结构·c++·算法·leetcode·贪心算法·github·动态规划
散峰而望2 天前
【算法练习】算法练习精选:从 Phone numbers 到 Decrease,覆盖字符串、模拟、图论思维题
数据结构·c++·算法·贪心算法·github·动态规划·图论
wabs6663 天前
关于贪心算法章节的【有两个维度问题】的自我总结
算法·贪心算法
重生之我是Java开发战士3 天前
【贪心算法】加油站,单调递增的数字,坏了的计算器,合并区间,用最少数量的箭引爆气球
算法·贪心算法
cheems95274 天前
[算法手记] 贪心 爬楼梯问题
算法·贪心算法
Hui Baby4 天前
K8S自定义API
容器·贪心算法·kubernetes
wabs6665 天前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
ん贤7 天前
KServe 详细笔记
笔记·算法·贪心算法
重生之我是Java开发战士9 天前
【贪心算法】最长回文串,增减字符串匹配,分发饼干,最优除法,跳跃游戏
游戏·贪心算法·哈希算法