开心消消乐

https://ac.nowcoder.com/acm/contest/9854/F

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const LL N=1e5+7;
const LL mod= 1e9+7;
int n;
int sum[N];//0的前缀和 
int pre[N];//记录[1,i]能消除的个数 
int rpre[N];//记录[i,n]原先能消除的个数 
int num[N][2];//0记录[1,i]连续0的个数 1记录[i,n]连续1的个数 
char s[N];

void init(){
    for(int i=1;i<=n;++i)    sum[i]=sum[i-1]+(s[i]=='1');
    stack<int>st;
    for(int i=1;i<=n;++i){
        pre[i]=pre[i-1];
        if(!st.size()){
            st.push(i);
            num[i][0]=(s[i]=='0');
            continue;
        }
        if(s[i]=='1'&&s[st.top()]=='0'){//01
            st.pop();
            pre[i]++;
            if (st.size())num[i][0] = num[st.top()][0];
            else num[i][0] = 0;
            continue;
        }
        num[i][0]=num[st.top()][0]+(s[i]=='0');//00 10 11情况 
        st.push(i);
    } 
    stack<int>pls;
    for (int i = n; i >= 1; i--){
        rpre[i] = rpre[i + 1];
        if (!pls.size()){
            pls.push(i);
            num[i][1] = (s[i] == '1');
            continue;
        }
        if (s[i] == '0' && s[pls.top()] == '1'){
            pls.pop();
            rpre[i]++;
            if (pls.size())num[i][1] = num[pls.top()][1];
            else num[i][1] = 0;
            continue;
        }
        if (pls.size())num[i][1] = num[pls.top()][1] + (s[i] == '1');
        else num[i][1] = (s[i] == '1');
        pls.push(i);
    }
}
int judge(int l,int r){
    int one=sum[r]-sum[l-1];
    int zero=r-l+1-one;
    return (one==2*zero);    
}
int find(int l,int r){
    if(judge(l,r)==0)    return n-2*pre[n];
    int y=pre[l-1]+rpre[r+1];
    int x=min(num[l-1][0],num[r+1][1]);
    return n-(r-l+1)-2*(x+y);
}
int main(){
    cin>>n;
    scanf("%s",s+1);
    init();
    int ans=n-2*pre[n];
    for(int i=1;i<=n;++i){
        for(int j=i+1;j<=n;++j){
            ans=min(ans,find(i,j));
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2021-04-14 14:18  PdrEam  阅读(57)  评论(0编辑  收藏  举报