ovo 的中间一定是个 v,那就别纠结整串,盯着每个 v 看它能配出多少组。
如果最后一共放了 k 个 o,当前前面已经有 j 个 o,那这个位置放 v 的贡献就直接是 j*(k-j);所以做个 DP,边走边决定这位放 o 还是 v,把贡献最大化。
void solve(){
string s;cin>>s;
int n=(int)s.size();
int c0=0,cq=0;
for(int i=0;i<n;++i){
if(s[i]=='o')++c0;
else if(s[i]=='?')++cq;
}
ll ans=0;
for(int i=c0;i<=c0+cq;++i){
vvll dp(n+1,vll(i+1,-LINF));
dp[0][0]=0;
for(int j=1;j<=n;++j){
char c=s[j-1];
for(int k=0;k<=i;++k){
if(c!='o'&&dp[j-1][k]!=-LINF){
dp[j][k]=max(dp[j][k],dp[j-1][k]+1LL*k*(i-k));
}
if(c!='v'&&k>0&&dp[j-1][k-1]!=-LINF){
dp[j][k]=max(dp[j][k],dp[j-1][k-1]);
}
}
}
ans=max(ans,dp[n][i]);
}
cout<<ans<<endl;
}

京公网安备 11010502036488号