题意:
个位置,给长度为的序列A,B。问每一位置在和中任选一个,恰好个A和B,得到不降的序列的方案(多种任意输出一种)。
思路:
- 引理
猜了一个结论:能够造出C的A的个数是连续的。
和CF之前打过一道题,一样的技巧。
这里给简略构造证明:
处理出A个数最少(Amin个)的序列C1,和A最大(Amax个)的序列C2。
考虑一步一步把C1变为C2。
归纳法:考虑前位已经每位对上了,现在对第位,一共有四种情况发现都能无后效性地匹配成功。(自己画一下……)
每一次相当于A个数+1(-1),B个数-1(+1)
因此在Amin到Amax中间个数的A一定也能构造出来。 - 构造
先用求:表示第位选,A的个数max/min值。
然后通过是否包含于判有无解。
从后往前构造(因为dp存的是前缀信息),记录表示上一个填的数值,表示当前需要的A的个数。
因为我们判了,就保证至少有一个解。
如果恰好只能填A/B中的一个(其中一个值比大),就直接填。
两个都行,就用引理判断一下即可。
code
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
const int inf=1e9;
int n,nn,a[N],b[N],mx[N][2],mn[N][2],Mx[N],Mn[N];
void DP() {
for(int i=1;i<=nn;i++) {
if(a[i-1]<=a[i]) mx[i][0]=mx[i-1][0]+1;
if(b[i-1]<=a[i]) mx[i][0]=max(mx[i][0],mx[i-1][1]+1);
if(a[i-1]<=b[i]) mx[i][1]=mx[i-1][0];
if(b[i-1]<=b[i]) mx[i][1]=max(mx[i][1],mx[i-1][1]);
// printf("i=%d : mx[i][0]=%d mx[i][1]=%d\n",i,mx[i][0],mx[i][1]);
Mx[i]=max(mx[i][0],mx[i][1]);
}
for(int i=1;i<=nn;i++) {
mn[i][0]=mn[i][1]=inf;
if(a[i-1]<=a[i]) mn[i][0]=mn[i-1][0]+1;
if(b[i-1]<=a[i]) mn[i][0]=min(mn[i][0],mn[i-1][1]+1);
if(a[i-1]<=b[i]) mn[i][1]=mn[i-1][0];
if(b[i-1]<=b[i]) mn[i][1]=min(mn[i][1],mn[i-1][1]);
// printf("i=%d : mn[i][0]=%d mn[i][1]=%d\n",i,mn[i][0],mn[i][1]);
Mn[i]=min(mn[i][0],mn[i][1]);
}
}
char pth[N];
void solve() {
// printf("%d %d\n",Mn[nn],Mx[nn]);
if(Mn[nn]>n||Mx[nn]<n) {printf("-1");return;}
int cnta=n,lst=inf;
for(int i=nn;i;i--) {
if(a[i]>lst) {pth[i-1]='B';lst=b[i];}
else if(b[i]>lst) {pth[i-1]='A';cnta--;lst=a[i];}
else {
// printf("i=%d: *%d [%d,%d]\n",i,cnta,Mn[i-1],Mx[i-1]);
if(mn[i][0]<=cnta&&cnta<=mx[i][0]) {cnta--;pth[i-1]='A';lst=a[i];}
else {pth[i-1]='B';lst=b[i];}
}
}
printf("%s",pth);
}
int main() {
// freopen("build.in","r",stdin);
// freopen("build.out","w",stdout);
scanf("%d",&n);nn=n<<1;
for(int i=1;i<=nn;i++)scanf("%d",&a[i]);
for(int i=1;i<=nn;i++)scanf("%d",&b[i]);
DP();
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人