小强有两个序列和,这两个序列都是由相同的无重复数字集合组成的,现在小强想把序列变成序列,他只能进行以下的操作:
从序列中选择第一个或者最后一个数字并把它插入中的任意位置。
问小强至少需要几次操作可以将序列变为序列。
一行一个整数表示序列的长度。
接下来两行每行个整数。
第一行表示序列,第二行表示序列。
保证给出的序列符合题意。
输出一行一个整数表示答案。
4 4 2 3 1 1 2 3 4
2
#include <bits/stdc++.h> typedef long long ll; using namespace std; int n,a[100005],b; map<int,int>mp; int main() { ios::sync_with_stdio(0),cin.tie(0); int i,j,ans=0,cnt=0; cin>>n; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=n;i++) cin>>b,mp[b]=i; for(i=1;i<=n;i++) a[i]=mp[a[i]]; for(i=1;i<=n;i++) { /**< 求最长连续上升子段,其他部分都得移动插入 */ if(a[i]>a[i-1]) ans=max(ans,++cnt); else cnt=1; } cout<<n-ans; return 0; }
#include <iostream> #include <vector> #include <unordered_map> using namespace std; int main() { int n; cin>>n; vector<int> a(n, 0); vector<int> b(n, 0); unordered_map<int, int> mp; for(int i=0; i<n; i++) cin>>a[i]; for(int i=0; i<n; i++) cin>>b[i]; for(int i=0; i<n; i++) mp[b[i]]=i; int cur=0; int ans=0; int lb=0; for(int i=0; i<n; i++) { if(mp[a[i]]>=lb) cur++; else { ans=max(ans, cur); cur=1; } lb=mp[a[i]]; } cout<<n-ans; return 0; }转化成最大连续上升子序列问题,子序列里面的元素可以不移动,子序列之外的元素需要移动插入到子序列中去,所以答案就是序列总长度减去最大连续上升子序列长度。
import java.util.HashMap; import java.util.Map; import java.util.Scanner; /** * @date 2021/8/27 - 16:04 */ public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); int n = cin.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = cin.nextInt(); } Map<Integer,Integer> map = new HashMap<>(); for (int i = 0; i < n; i++) { map.put(cin.nextInt(),i); } // 将序列表示成b的下标 for (int i = 0; i < n; i++) { a[i] = map.get(a[i]); } // 求下标最长连续上升序列 int max = 1; int cur = 1; // 从第二个开始计算 for (int i = 1; i < a.length; i++) { if(a[i]>a[i-1]) { cur++; max = Math.max(max,cur); }else { cur = 1; } } System.out.println(n-max); } }
n = int(input()) a = list(map(int, input().split())) b = list(map(int, input().split())) r = {} for i in range(1, n + 1) : r[b[i - 1]] = i for i in range(n) : a[i] = r[a[i]] cnt, ans = 1, 1 for i in range(1, n) : if a[i] > a[i - 1] : cnt += 1 ans = max(ans, cnt) else : cnt = 1 print(n - ans)
import java.util.*; public class Main { /* 更改题目 a=[D,B,C,A]; b=[A,B,C,D] 对 b 做映射 A->0; B->1; C->2; D->3 那么对应的 a 可根据映射规则更改为 a'=[3,1,2,0] 之后对 a' 做最长连续上升子数组即可 */ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; int[] b = new int[n]; for (int i = 0; i < n; i ++) { a[i] = sc.nextInt(); } for (int i = 0; i < n; i ++) { b[i] = sc.nextInt(); } // 对 A 里面的数进行重新映射 Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < n; i ++) { map.put(b[i], i); } // 利用映射规则对 B 进行更新映射 for (int i = 0; i < n; i ++) { a[i] = map.get(a[i]); } // 对更改之后的 b 做最长连续上升子序列 int res = 0; int cur = 1; for (int i = 1; i < n; i ++) { if (a[i]>a[i-1]) { cur += 1; res = Math.max(res, cur); } else { cur = 1; } } System.out.println(n - res); } }
import sys read = sys.stdin.readline n = int(read()) a_arr = list(map(int, read().split())) b_arr = list(map(int, read().split())) # a_map = {} b_map = {} for i in range(n): # a_map[a_arr[i]] = i b_map[b_arr[i]] = i ans = 1 cnt = 1 for i in range(1, n): # if a_map[b_arr[i - 1]] < a_map[b_arr[i]]: if b_map[a_arr[i - 1]] < b_map[a_arr[i]]: cnt += 1 ans = max(ans, cnt) else: cnt = 1 print(n - ans)