题解:P11447 「ALFR Round 3」C 割
zhanghy123 · · 题解
思路
不难想到一个性质:字符串
现在要分成
那么,问题就转化为将
- 当
cnt 不能被k 整除时,最大字符最多的区间s 的f(s) 就有\lceil\frac{cnt}{k}\rceil 个字符。此时我们可以将该区间放在前面,最终答案就是\lceil\frac{cnt}{k}\rceil 个最大字符; - 当能整除时,因为需要平均分配,所以这整个字符串最后一个最大字符的末尾就没有分割点。此时,最后一个最大字符后面还有冗余字符,需要再跑一遍单调栈,把这些冗余字符组成的串的最大字典序子序列拼接在
\frac{cnt}{k} 个最大字符之后。
总结:最终答案为
code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,k,pos[200001],cnt,top;
string s,ans1,ans2;
char maxx,stk[200001];
void ddz(int begin)//单调栈求以 begin 为起点的最大字典序子序列
{
for(int i=begin; i<n; i++)
{
while(top && stk[top]<s[i]){top--;}
stk[++top]=s[i];
}
for(int i=1; i<=top; i++)
cout<<stk[i];
}
int main()
{
cin>>n>>k>>s;
for(int i=0; i<n; i++)
maxx=max(s[i],maxx);
for(int i=0; i<n; i++)
if(s[i]==maxx) pos[++cnt]=i;
if(k==1){
ddz(0);
return 0;
}
for(int i=1; i<=ceil(cnt*1.0/k); i++)
cout<<maxx;
if(cnt%k==0)//能整分,最后一段需要再求一次
ddz(pos[cnt]+1);
return 0;
}