原题地址:https://www.luogu.org/problem/show?pid=3615
题目数据范围较大,将所有字串连接为一个字串处理会超时。所以每个字串处理完后根据字串情况进行统计。
可以发现,题目有三种情况
1、男生人数大于》n,这正情况下是-1;
2、男女生人数相等,
3、女生人数大于男生人数。
首先考虑正序,遇到女生+1,遇到男生-1,那么在人数相等的情况下,前面的女生多了,就需要将其向后调整。所以记录女生比男生多出的人数最大值ans,结果就是ans-1.
如果女生人数比男生人数多,那么前面的男女共用厕所可以排更多的女生,可以排多少呢?设男生人数为cnt,那么男生用男女共用厕所的人数是cnt,剩下的n-cnt个厕位是女生可以用的,加上同时在用女厕的人数,所以女生比男生多2*(n-cnt)个,所以有ans-1-2*(n-cnt).也就是相当于将多的女生拿出来后,在男女生一样多的情况一样了。
代码修改自:ljm
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
long long ans=1,sum,n,m,x,l,p,q,cnt,maxp;
char s[233333];
int main()
{
scanf("%lld%lld",&n,&m);
for(long long i=1;i <= m;i++){
for(long long k=1;s[k];s[k++]=0);
scanf("%s%lld",s+1,&x);
l = strlen(s+1);
p = sum,q = cnt;maxp=-1;
int fc=0,mc=0 ;
for(long long i=1;i <= l;i++){
sum += s[i] == 'F' ? 1 : -1, ans = max(ans,sum);
if(s[i] == 'M')cnt++,fc++;
else {
mc++;
if(sum==ans)maxp=i;
}
}
cnt += (cnt-q)*(x-1);
sum += (sum-p)*(x-1);
if(maxp!=-1&&mc>fc)ans+=(mc-fc)*(x-1);
ans = max(ans,sum);
}
if(cnt > n)puts("-1\n");
else
printf("%lld\n",max((long long)0,ans-1-2*(n-cnt)));
return 0;
}
也可以考虑逆序,经过上面的分析,我们发现,在女生大于男生的情况下,排在后面的男生不能在最后连续排列, ,所以我们只需要从后向前记录,假设男生为+1,女生为-1,那么记录男生的最大值即可。
代码参考洛谷题解。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 100005
int m;
long long sum,ans,sM,sF,k[maxn],n;
string s[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for (int i=1;i<=m;i++) cin>>s[i]>>k[i];
for (int i=m;i>=1;i--)
{
int len=s[i].length();
long long w1=0,w2=0,cntM=0,cntF=0;
for (int j=len-1;j>=0;j--)
{
if (s[i][j]=='M') w1++,cntM++;else w1--,cntF++;
ans=max(ans,w1+sum);
}
sM+=k[i]*cntM;sF+=k[i]*cntF;
for (int j=len-1;j>=0;j--)
ans=max(ans,w1*k[i]+sum);
sum=sum+w1*k[i];
}
if (sM>sF) cout<<"-1"<<endl;
else cout<<max(ans-1,0ll)<<endl;
return 0;
}