原文链接
题意
给定一个长度为 $2n$ 的字符串,包含 $n$ 个 $‘a‘$ 和 $n$ 个 $‘b‘$ 。
现在,让你按照原顺序取出一些字符,按照原顺序组成新的字符串,输出所有满足条件的字符串中字典序最大的?(字典序: $b>a>""$)
条件限制:当且仅当取了原序列的第 $i$ 个 $‘a‘$ 时,原序列的第 $i$ 个 $‘b‘$ 也被取了。
$n\leq 3000$
题解
代码
#include <bits/stdc++.h> using namespace std; const int N=6005; int n,p[N],pp[N],t[N]; int q[N],head,tail; string res[N],now; char s[N]; vector <int> a,b; int main(){ scanf("%d",&n); n<<=1; scanf("%s",s+1); a.clear(),b.clear(); for (int i=1;i<=n;i++) if (s[i]==‘a‘) a.push_back(i); else b.push_back(i); for (int i=1;i<=n/2;i++) p[b[i-1]]=a[i-1],pp[a[i-1]]=b[i-1]; for (int i=1;i<=n+1;i++) res[i]=""; int tot=0; int nxt=n+1; for (int i=n;i>=1;i--){ if (s[i]==‘a‘) tot++; else tot--; if (tot) continue; memset(t,0,sizeof t); head=1,tail=0; res[i]=res[nxt]; for (int j=i;j<nxt;j++){ if (s[j]==‘a‘){ if (t[j]){ now=""; for (int k=i;k<nxt;k++) if (s[k]==‘b‘){ if (t[k]||k>j) now+="b"; } else if (t[k]||k>p[q[tail]]) now+="a"; res[i]=max(res[i],now+res[nxt]); head++; t[j]=t[pp[j]]=0; } continue; } if (p[j]<j) continue; q[++tail]=j; t[j]=t[p[j]]=1; } memset(t,0,sizeof t); if (tail==0){ for (int j=i;j<nxt;j++){ if (s[j]==‘b‘) continue; t[j]=t[pp[j]]=1; now=""; for (int k=i;k<=pp[j];k++) if (t[k]) now+=s[k]; res[i]=max(res[i],now+res[nxt]); j=pp[j]; } } nxt=i; } cout << res[1]; return 0; }
原文地址:https://www.cnblogs.com/zhouzhendong/p/AGC026E.html
时间: 2024-09-30 21:35:28