AtCoder Grand Contest 026 (AGC026) E - Synchronized Subsequence 贪心 动态规划
Posted zhouzhendong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Grand Contest 026 (AGC026) E - Synchronized Subsequence 贪心 动态规划相关的知识,希望对你有一定的参考价值。
原文链接
题意
给定一个长度为 $2n$ 的字符串,包含 $n$ 个 $‘a‘$ 和 $n$ 个 $‘b‘$ 。
现在,让你按照原顺序取出一些字符,按照原顺序组成新的字符串,输出所有满足条件的字符串中字典序最大的?(字典序: $b>a>""$)
条件限制:当且仅当取了原序列的第 $i$ 个 $‘a‘$ 时,原序列的第 $i$ 个 $‘b‘$ 也被取了。
$nleq 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; }
以上是关于AtCoder Grand Contest 026 (AGC026) E - Synchronized Subsequence 贪心 动态规划的主要内容,如果未能解决你的问题,请参考以下文章
Atcoder Grand Contest 026 (AGC026) F - Manju Game 博弈,动态规划
AtCoder Grand Contest 026 (AGC026) E - Synchronized Subsequence 贪心 动态规划