题目链接
题目大意
就是贪心的思路
最优解的一定是:前缀的?全部为1/0,后缀的?全部为0/1
根据(x,y)的大小来确定前缀和后缀的01
然后实现起来发现一个jls的写法很巧妙,只要记录数量以及和即可
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
char s[maxn];
ll x,y;
ll c0,s0,c1,s1;
signed main(){
scanf("%s %lld %lld",s+1,&x,&y);
int n=strlen(s+1);
if(x>y){
swap(x,y);
for(int i=1;i<=n;i++){
if(s[i]=='0'){
s[i]='1';
}else if(s[i]=='1'){
s[i]='0';
}
}
}
vector<int> vec;
for(int i=1;i<=n;i++){
if(s[i]=='0'){
c0++;
s0+=i;
}else if(s[i]=='1'){
c1++;
s1+=i;
}else if(s[i]=='?'){
c1++;
s1+=i;
vec.push_back(i);
}
}
ll ans=1e18;
for(int i=0;i<vec.size();i++){
ans=min(ans,(s1-c1*(c1+1)/2)*x+(s0-c0*(c0+1)/2)*y);
c0++,c1--;
s0+=vec[i],s1-=vec[i];
}
ans=min(ans,(s1-c1*(c1+1)/2)*x+(s0-c0*(c0+1)/2)*y);
printf("%lld
",ans);
return 0;
}