【01串问题】

【01串问题】

结论题

小红的好01串修改

https://ac.nowcoder.com/acm/contest/114111/C

题目大意

image

思路

首先要发现一些显然的结论
(1)01串要相邻两不同->很显然只有两种方式:01010101/10101010
(2)每次修改相邻的两个->当一个点不满足要求的时候必须要改,下一个点跟着改就行
因为每个点都会被枚举到,所以直接一个方向扫一遍即可
->无解的情况?最后一个点不能被改

代码

const int N=3e5+10;
int n;
string s;
string ss;
void solve(){
	cin>>n;
    cin>>s;
    ss=s;
    string tmp1,tmp2;
    int idx=0;
    for(int i=0;i<n;i++){
        tmp1+=(char)(idx+'0');
        idx^=1;
    }
    idx=1;
    for(int i=0;i<n;i++){
        tmp2+=(char)(idx+'0');
        idx^=1;
    }
    int flag1=1,ans1=0;
    for(int i=0;i<n;i++){
        if(i==n-1){
            if(tmp1[i]!=s[i]){
                flag1=0;
                continue;
            }
        }
        if(tmp1[i]!=s[i]){
            ans1++;
            s[i]=tmp1[i];
            if(s[i+1]=='1') s[i+1]='0';
            else s[i+1]='1';
        }
    }
    s=ss;
    //cout<<tmp1<<" "<<tmp2<<endl;
    int flag2=1,ans2=0;
    for(int i=0;i<n;i++){
        if(i==n-1){
            if(tmp2[i]!=s[i]){
                flag2=0;
                continue;
            }
        }
        if(tmp2[i]!=s[i]){
            ans2++;
            s[i]=tmp2[i];
            if(s[i+1]=='1') s[i+1]='0';
            else s[i+1]='1';
        }
    }
    int ans=inf_int;
    if(flag1) ans=min(ans,ans1);
    if(flag2) ans=min(ans,ans2);
    if(ans==inf_int) cout<<"-1"<<endl;
    else cout<<ans<<endl;
}

DP

Flip to Gather

https://atcoder.jp/contests/abc408/tasks/abc408_d

题目大意

1->0 0->1可以随意转换 ->这里看出可以设状态dp
最后只能留1串连续的1

代码

int n;
string s;
/*
每个都可以反转->有状态->【线性dp】
dp[i][j]
第二维状态:0 还没开始选->0 只能由“没开始选”状态转移来
           1 开始选了但是没选完->1 可以是第一个开始选的 也可以是之前选过的
           2 已经选完了->2 可以是第一个地方不选的 也可以是之前就不选的
            +1 代表修改
*/
void solve(){
    cin>>n;
    cin>>s;
    s=' '+s;
    vector<array<int,3>> dp(n+1,{INF_INT,INF_INT,INF_INT});
    dp[0]={0,0,0};
    for(int i=1;i<=n;i++){
        if(s[i]=='1'){
            dp[i][0]=dp[i-1][0]+1;
            dp[i][1]=min(dp[i-1][1],dp[i-1][0]);
            dp[i][2]=min(dp[i-1][1]+1,dp[i-1][2]+1);
        }
        else{
            dp[i][0]=dp[i-1][0];
            dp[i][1]=min(dp[i-1][1]+1,dp[i-1][0]+1);
            dp[i][2]=min(dp[i-1][1],dp[i-1][2]);
        }
    }
    int ans=min(dp[n][0],min(dp[n][1],dp[n][2]));
    cout<<ans<<endl;
}
posted @ 2025-06-01 13:19  White_ink  阅读(13)  评论(0)    收藏  举报