20201024B组 密州盛宴
题目
TJ
显然,在一个后缀中,若 0 0 0的个数比 1 1 1的个数多 2 2 2,那么这个后缀显然是不合法的,要将其中一个0往前移。
所以将0看成1,1看成-1,算后缀和,然后将最大的后缀和 − 1 -1 −1就是答案。
当然,要是1的个数小于 n n n,可以直接无解了。
#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
const int INF=1e9+7;
using namespace std;
const int N=1e6;
const int M=1e5;
ll n,m,a,b,a1,b1,ans,s[M+10],s1[M+10],x[M+10],len,sum;
char st[N+10];
int main(){
freopen("meal.in","r",stdin);
freopen("meal.out","w",stdout);
scanf("%lld%lld",&n,&m);
while(n || m){
a=b=0;
ans=0;
sum=0;
fo(i,1,m){
scanf("%s",st+1);
scanf("%lld",&x[i]);
len=strlen(st+1);
a1=b1=0;
s1[i]=s[i]=0;
fd(j,len,1){
if(st[j]=='0')s[i]++,a1++;
else s[i]--,b1++;
s1[i]=max(s[i],s1[i]);
}
a+=a1*x[i];b+=b1*x[i];
}
fd(i,m,1){
ans=max(ans,sum+s1[i]-1);
ans=max(ans,sum+s[i]*(x[i]-1)+s1[i]-1);
sum+=s[i]*x[i];
}
if(a>b)printf("-1\n");
else printf("%lld\n",ans);
scanf("%lld%lld",&n,&m);
}
return 0;
}