Educational Codeforces Round 76 E. The Contest (最长不下降子序列)

题目描述

A team of three programmers is going to play a contest. The contest consists of n problems, numbered from 1 to n. Each problem is printed on a separate sheet of paper. The participants have decided to divide the problem statements into three parts: the first programmer took some prefix of the statements (some number of first paper sheets), the third contestant took some suffix of the statements (some number of last paper sheets), and the second contestant took all remaining problems. But something went wrong — the statements were printed in the wrong order, so the contestants have received the problems in some random order.
The first contestant has received problems a1,1,a1,2,…,a1,k1. The second one has received problems a2,1,a2,2,…,a2,k2. The third one has received all remaining problems (a3,1,a3,2,…,a3,k3).
The contestants don’t want to play the contest before they redistribute the statements. They want to redistribute them so that the first contestant receives some prefix of the problemset, the third contestant receives some suffix of the problemset, and the second contestant receives all the remaining problems.
During one move, some contestant may give one of their problems to other contestant. What is the minimum number of moves required to redistribute the problems?
It is possible that after redistribution some participant (or even two of them) will not have any problems.

Input

The first line contains three integers k1,k2 and k3 (1≤k1,k2,k3≤2⋅105,k1+k2+k3≤2⋅105) — the number of problems initially taken by the first, the second and the third participant, respectively.
The second line contains k1 integers a1,1,a1,2,…,a1,k1 — the problems initially taken by the first participant.
The third line contains k2 integers a2,1,a2,2,…,a2,k2 — the problems initially taken by the second participant.
The fourth line contains k3 integers a3,1,a3,2,…,a3,k3 — the problems initially taken by the third participant.
It is guaranteed that no problem has been taken by two (or three) participants, and each integer ai,j meets the condition 1≤ai,j≤n, where n=k1+k2+k3.

Output

Print one integer — the minimum number of moves required to redistribute the problems so that the first participant gets the prefix of the problemset, the third participant gets the suffix of the problemset, and the second participant gets all of the remaining problems.

Examples

input
2 1 2
3 1
4
2 5
output
1
input
3 2 1
3 2 1
5 4
6
output
0
input
2 1 3
5 6
4
1 2 3
output
3
input
1 5 1
6
5 1 2 4 7
3
output
2

Note

In the first example the third contestant should give the problem 2 to the first contestant, so the first contestant has 3 first problems, the third contestant has 1 last problem, and the second contestant has 1 remaining problem.
In the second example the distribution of problems is already valid: the first contestant has 3 first problems, the third contestant has 1 last problem, and the second contestant has 2 remaining problems.
The best course of action in the third example is to give all problems to the third contestant.
The best course of action in the fourth example is to give all problems to the second contestant.

题目大意

有三个人去参加比赛,有一些问题要给这三个人去解决。第一个人要做前面的题目,第三个人要做后面的题目,剩下的题目给第二个人做。
但给三个人的题目并不是这样分配的,我们每次移到都可以将一个人的一道题目给另一个人。要怎么移到才能使题目的分配满足三个人的条件,求最小移到次数。

题目分析

把第一个人分到的记为1,第二个人分到的题记为2,第三个人分到的题记为3。
如样例一:
2 1 2
3 1
4
2 5
题号 1 2 3 4 5
记录 1 3 1 2 3
然后要将这个记录的数组st[],分割成三部分,使得第一部分中1尽可能多,第二部分中2尽可能多,第三部分中3尽可能的多。
如样例一:
1 3 1 2 3 ——>
一:1 3 1
二:2
三:3
最后的结果即为第一部分中的非1数+第二部分中的非2数+第三部分中的非3数。 因为我们要将小的数移到第一部分中,大的数移到第三部分中。
如样例一:
分割完一中最后应该有1 2 3这三个数,但2在第三组,因此我们要把2移到第一组中,即把第一部分中的3改为1。第二部分中全是2,第三部分中全是3,则不用进行修改(移到)。
所以样例一的答案为1。

但是找出要进行修改的数不太容易,因此我们可以找出不用修改的数,最后用总数减去不用修改的数即为答案。而不用修改的数即为st[]数组中的最长不下降子序列中的数。这个题就变为了求st[]数组的最长不下降子序列的长度。

代码如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <iomanip>
#define LL long long
using namespace std;
const int N=2e5+5;
int s[N],st[N];		//s[]记录最长不下降子序列
int main()
{
	int n,a,b,c;
	scanf("%d %d %d",&a,&b,&c);
	n=a+b+c;
	for(int i=1;i<=a;i++)		//求st[]的过程
	{
		int x; 
		scanf("%d",&x);
		st[x]=1;
	}
	for(int i=1;i<=b;i++) 
	{
		int x;
		scanf("%d",&x);
		st[x]=2;
	}
	for(int i=1;i<=c;i++)
	{
		int x;
		scanf("%d",&x);
		st[x]=3;
	}
	int len=0;		//记录最长不下降子序列的长度
	for(int i=1;i<=n;i++)
		if(len==0||s[len-1]<=st[i]) s[len++]=st[i];
		else
		{
			int k=upper_bound(s,s+len,st[i])-s;
			s[k]=st[i];
		}
	printf("%d\n",n-len);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lwz_159

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值