【JOISC 2020 Day1】building4

题目

The Olympic Games will be held in JOI Kingdom soon. In order to welcome participants from all over
the world, the buildings on the way from the airport to the accommodation will be decorated. There are 2N
buildings, numbered from 1 to 2N from the airport.
President K is in charge of the decoration project. He asked the public to make decoration plans. After
examining them, he finally chose two plans, the plan A and the plan B. In the plan A, the luxury level of the
building i (1 ≤ i ≤ 2N) is Ai
. In the plan B, the luxury level of the building i (1 ≤ i ≤ 2N) is Bi.
Both plans are very good, and it is difficult to choose one of them. He decided to decorate the buildings in the
following way: for each building, one of the plan A or B will be chosen. In order to decorate the buildings in a
fair way, the plan A will be chosen for N buildings, and the plan B will be chosen for the remaining N buildings.
Moreover, since the participants will be excited if the luxury levels are increasing on the way from the airport
to the accommodation, the following condition should be satisfied: Ci ≤ Ci+1 for every i with 1 ≤ i ≤ 2N 1,
where Ci
is the luxury level of the building i (1 ≤ i ≤ 2N).
Write a program which, given the number of buildings and the luxury levels of the buildings for each plan,
decides whether it is possible to choose decoration plans satisfying the above condition, and output one way to
decorate the buildings if it is possible.
Input
Read the following data from the standard input. All the values in the input are integers.
NA1 · · · A2N B1 · · · B2N
Output
If it is impossible to choose decoration plans satisfying the condition, output -1 to the standard output.
Otherwise, output a string S of length 2N describing a way to decorate the buildings to the standard output.
Here the i-th character of S (1 ≤ i ≤ 2N) is A if the plan A is chosen for the building i, and is B if the plan B is
chosen for the building i. If there are multiples ways satisfying the condition, output any of them.
Building 4– 1 / 3
The 19th Japanese Olympiad in Informatics (JOI 2019/2020)
Spring Training Camp/Qualifying Trial
March 20–23, 2020 (Komaba, Tokyo)
Contest Day 1 – Building 4
Constraints
• 1 ≤ N ≤ 500 000. • 1 ≤ Ai ≤ 1 000 000 000 (1 ≤ i ≤ 2N).
• 1 ≤ Bi ≤ 1 000 000 000 (1 ≤ i ≤ 2N).
Subtasks

  1. (11 points) N ≤ 2 000.
  2. (89 points) No additional constraints.
    Sample Input and Output
    Sample Input 1 Sample Output 1
    3
    2 5 4 9 15 11
    6 7 6 8 12 14
    AABABB
    Choose the plan A, A, B, A, B, B for each building, respectively. Then both the plan A and B are chosen
    three times. The luxury level of each building is 2, 5, 6, 9, 12, 14, respectively. The condition is satisfied.
    Sample Input 2 Sample Output 2
    2
    1 4 10 20
    3 5 8 13
    BBAA
    If there are more than one ways to decorate the buildings satisfying the condition, your program may output
    any one of them.
    Sample Input 3 Sample Output 3
    2
    3 4 5 6
    10 9 8 7
    -1
    Since it is impossible to choose decoration plans satisfying the condition, output -1.
    Building 4– 2 / 3
    The 19th Japanese Olympiad in Informatics (JOI 2019/2020)
    Spring Training Camp/Qualifying Trial
    March 20–23, 2020 (Komaba, Tokyo)
    Contest Day 1 – Building 4
    Sample Input 4 Sample Output 4
    6
    25 18 40 37 29 95 41 53 39 69 61 90
    14 18 22 28 18 30 32 32 63 58 71 78

思路

设DP状态f[i][0/1][j]表示前ii个数字,总共有jj个选择了A,上一个选择了A/B是否合法,直接暴力复杂度O(n^2)

观察性质,可以证明对于每个i,其合法的肯定为一个连续段。

因此转移只需要记录左右端点。复杂度O(n)

代码

#include<bits/stdc++.h>
#define pii pair<int,int>
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
using namespace std;
const int INF=1<<30;
const int N=1000005;
int n,a[N],b[N];
pii f[N][2];
char yjy[N];
void upd(pii &x,pii y)
{
	x.first=min(x.first,y.first);
	x.second=max(x.second,y.second);
}
int main()
{
	scanf("%d",&n);
	For(i,1,2*n) scanf("%d",&a[i]);
	For(i,1,2*n) scanf("%d",&b[i]); 
	f[0][0]=f[0][1]=pii(0,0);
	For(i,1,2*n)
	{
		f[i][0]=f[i][1]=pii(INF,-INF);
		if (a[i-1]<=a[i]) upd(f[i][0],f[i-1][0]);
		if (b[i-1]<=a[i]) upd(f[i][0],f[i-1][1]);
		if (a[i-1]<=b[i]) upd(f[i][1],f[i-1][0]);
		if (b[i-1]<=b[i]) upd(f[i][1],f[i-1][1]);
		++f[i][1].first; ++f[i][1].second;
	}
	int fl=-1,rem=n;
	For(i,0,1)
		if (f[2*n][i].first<=n&&n<=f[2*n][i].second)
			fl=i;
	if (fl==-1)
		return puts("-1"),0;
	Rep(i,2*n,1)
	{
		yjy[i]=(fl?'B':'A');
		rem-=fl;
		int v=(fl?b[i]:a[i]);
		if (a[i-1]<=v&&f[i-1][0].first<=rem&&rem<=f[i-1][0].second) fl=0;
		else assert(b[i-1]<=v&&f[i-1][1].first<=rem&&rem<=f[i-1][1].second),fl=1;
	}
	printf("%s\n",yjy+1);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值