oj记录 codeforces 1680 C.Binary String (思维

题目描述

  • You are given a string s consisting of characters 0 and/or 1.
  • You have to remove several (possibly zero) characters from the beginning of the string, and then several (possibly zero) characters from the end of the string. The string may become empty after the removals. The cost of the removal is the maximum of the following two values:
  1. he number of characters 0 left in the string;
  2. the number of characters 1 removed from the string.
    What is the minimum cost of removal you can achieve?

题意

给定一个01串,任意截取一段子串(可空),使花费最小
花费计算方法:max(区间内的0的个数, 区间外的1个数)

思路

  • l,r指针用于选择截取的子串区间
  • 显然当r的下一个元素是’1’时,r必须++,因为这样减少了区间外1的个数,对得到更优的答案有利;同理l当前所指元素为’0’时,l必须++.
  • 经过上面的操作,r的下一个元素一定是’0’,l所指元素一定是’1’.两个指针向后移动都对得到更优的结果不利.现在要决定下面该移动哪个指针:
    如果区间内0的个数>区间外1的个数,那么想要得到更优的答案,就要减少区间内0的个数,那么就要缩小区间范围,即l++;同理,相反情况r++.

code

#include<bits/stdc++.h>
// #define DEBUG(x) #x<<':'<<(x)<<' '
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
// const int mod=1e9+7;

void solv()
{   
    string s;
    int left0,del1,l,r,ans;
    cin>>s;
    int num0=0,num1=0,n=s.size();
    for(int i=0;i<n;i++)
        if(s[i]=='0')num0++;
        else num1++;
    left0=0;
    del1=num1;
    ans=del1;
    l=0,r=-1;
    // max(0 left , 1 deleted)
    do
    {
        while(r+1<n&&s[r+1]=='1')
        {
            r++;
            del1--;
        }
        while(l+1<=r&&s[l]=='0')
        {
            l++;
            left0--;
        }

        ans=min(max(left0,del1),ans);
        
        if(left0<=del1)
        {
            r++;
            left0++;
        }
        else
        {
            l++;
            del1++;
        }
        ans=min(max(left0,del1),ans);

    }while((l<=r&&r<n));

    cout<<ans<<'\n';
}

int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int T=1;
    cin>>T;
    while(T--)
    {
        solv();
    }
    return 0;
}

注意与总结

知识补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值