通过题目描述我们可知这是一个最长上升序列的类似题目,而我们需要注意路径问题,即在求出最长子序列长度的同时还要记录当前的最长子序列,因此我们依然可以用二分优化来做题,我们需要用ans来存储答案路径,同时用res来充当二分查找的方案利用dp不断更新路径,最后直接输出ans[len]即可
上代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
string s[N], ans[N], res[N];//分别存储所有人的名字,答案路径以及用于查找二分位置随时更新
int main(void)
{
int cnt = 0;
string str; cin >> str;
for(int i = 0; i < str.size(); i++){
if(str[i] >= 'A' && str[i] <= 'Z') s[++cnt] += str[i];//如果是大写字母说明是下一个人的名字,就更新cnt
else s[cnt] += str[i];
}
int len = 0;//初始化子序列长度
for(int i = 1; i <= cnt; i++){
int pose = lower_bound(res + 1, res + 1 + len, s[i]) - res;//寻找第一个小于s[i]的下标
res[pose] = s[i];
ans[pose] = ans[pose - 1] + s[i];
len = max(len, pose);
}
cout << ans[len] << endl;//因为ans存储着答案路径,因此直接输出ans即可
return 0;
}