1.最长上升子序列,用二分+贪心算法优化的那个
2.分割提取游客名字,与蓝肽子序列类似
3.关键是我不知道怎么输出答案序列,这里学习了一种不按序实现的,思想是倒序能凑上就加入,反正从ma开始遍历,生成一定是答案之一
P8736 [蓝桥杯 2020 国 B] 游园安排 - 洛谷
#include<bits/stdc++.h>
using namespace std;
#define N 100011
typedef long long ll;
typedef pair<int,int> pii;
string s;
int l[N],n;
string g[N];
string an[N];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
vector<string> a;
cin>>s;
string b;
for(int i=0;i<s.size();i++)///分割提取游客名字
{
if(s[i]>='A'&&s[i]<='Z')
{
if(b!="")a.push_back(b);
b="";
b.insert(b.end(),s[i]);
}else b.insert(b.end(),s[i]);
}
if(b!="")a.push_back(b);
n=a.size();
for(int i=0;i<n;i++) g[i]="zzzzzzzzzzzzzzzzz";
int cl=0;
for(int i=0;i<n;i++)
{
int p=lower_bound(g,g+n,a[i])-g;///用二分贪心实现的最长上升子序列算法
g[p]=a[i];
l[i]=p+1;
cl=max(p+1,cl);
}
int x=0;
for(int i=n-1;i>=0;i--)///倒序输出最长上升子序列
///主打一个能凑成就行
///因为可能有多个,而题目要求输出字典序最小的
///这个做不到,但是容易理解
{
if(l[i]==cl)
{
an[x++]=a[i];
cl--;
}
}
for(int i=x-1;i>=0;i--) cout<<an[i];
return 0;
}