JOISC2020DAY1建筑装饰4


一个结论:

构成递增序列,最少需\(Al\)个最多\(r\)个,那么\(l\)\(r\)间的个数都可以实现

\(DP\)就好,找方案就倒着看是否合法

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f==1?x:-x;
}
const int N=5e5+4;
int n,mn,mx,a[N<<1],b[N<<1],f0[N<<1][2],f1[N<<1][2];
void out(int x,int re,int fl){
	if(!x)return;
	int r=(fl?b[x]:a[x]);
	if(a[x-1]<=r&&f0[x-1][0]<=re&&re<=f1[x-1][0])out(x-1,re-1,0);
	else out(x-1,re,1);
	fl?putchar('B'):putchar('A');
}
int main(){
	n=read();
	for(int i=1;i<=(n<<1);i++)a[i]=read();
	for(int i=1;i<=(n<<1);i++)b[i]=read();
	for(int i=1;i<=(n<<1);i++){
		f0[i][0]=f0[i][1]=(n<<1)+1;
		if(a[i]>=a[i-1]){
			f0[i][0]=min(f0[i][0],f0[i-1][0]+1);
			f1[i][0]=max(f1[i][0],f1[i-1][0]+1);
		}
		if(a[i]>=b[i-1]){
			f0[i][0]=min(f0[i][0],f0[i-1][1]+1);
			f1[i][0]=max(f1[i][0],f1[i-1][1]+1);
		} 
		if(b[i]>=a[i-1]){
			f0[i][1]=min(f0[i][1],f0[i-1][0]);
			f1[i][1]=max(f1[i][1],f1[i-1][0]);
		}
		if(b[i]>=b[i-1]){
			f0[i][1]=min(f0[i][1],f0[i-1][1]);
			f1[i][1]=max(f1[i][1],f1[i-1][1]);
		}
	}
	mn=min(f0[n<<1][0],f0[n<<1][1]);
	mx=max(f1[n<<1][0],f1[n<<1][1]);
	if(!(mn<=n&&n<=mx)){puts("-1");return (0-0);}
	if(f0[n<<1][1]<=n&&n<=f1[n<<1][1])out(n<<1,n,1);
	else out(n<<1,n-1,0);
	return (0-0);
}

猜你喜欢

转载自www.cnblogs.com/aurora2004/p/12552261.html